Không có một phương thức tương đương chính xác nào để chuyển đổi một truy vấn Postgresql sử dụng SELECT DISTINCT ON sang MySQL.
Postgresql CHỌN DISTINCT BẬT
Trong Postgresql, truy vấn sau sẽ loại bỏ tất cả các hàng có biểu thức (col1, col2, col3)
khớp và nó sẽ chỉ giữ lại "hàng col4, col5 đầu tiên" cho mỗi tập hợp các hàng đã so khớp:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Vì vậy, nếu bảng của bạn như thế này:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
truy vấn của chúng tôi sẽ chỉ giữ một hàng cho (1,2,3) và một hàng cho (3,3,3). Các hàng kết quả sau đó sẽ là:
col4 | col5
-----------
777 | 888
555 | 555
vui lòng lưu ý rằng "hàng đầu tiên" của mỗi tập hợp là không thể đoán trước, hàng nắm tay của chúng tôi cũng có thể là (888, 999) trừ khi chúng tôi chỉ định ĐẶT HÀNG BẰNG CÁCH:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(DISTINCT trên biểu thức phải khớp với biểu thức ORDER BY ngoài cùng bên trái, nhưng ORDER BY có thể chứa các biểu thức bổ sung).
Tiện ích mở rộng MySQL cho GROUP BY
MySQL mở rộng việc sử dụng GROUP BY để chúng ta có thể chọn các cột không tổng hợp không có tên trong mệnh đề GROUP BY. Bất cứ khi nào chúng tôi chọn các cột không được tổng hợp, máy chủ có thể tự do chọn bất kỳ giá trị nào từ mỗi nhóm từ cột đó, vì vậy giá trị kết quả sẽ được xác định.
Vì vậy, truy vấn Postgresql này:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
có thể được coi là tương đương với truy vấn MySQL này:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
cả Postgresql và MySQL sẽ trả về "Hàng đầu tiên" cho mỗi (col1, col2, col3) và trong cả hai trường hợp, hàng trả về là không thể đoán trước vì chúng tôi không chỉ định và sắp xếp theo mệnh đề.
Rất nhiều người sẽ rất muốn chuyển đổi truy vấn Postgresql này bằng một ĐẶT HÀNG BẰNG CÁCH:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
với cái này:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
ý tưởng ở đây là áp dụng ORDER BY cho một truy vấn con để khi MySQL nhóm theo col1, col2, col3, nó sẽ giữ giá trị gặp phải đầu tiên cho col4 và col5. Ý tưởng là tốt, nhưng nó sai! MySQL có thể tự do chọn bất kỳ giá trị nào cho col4 và col5 và chúng tôi không biết đâu là giá trị đầu tiên gặp phải, nó phụ thuộc vào trình tối ưu hóa. Vì vậy, tôi sẽ sửa nó thành điều này:
SELECT t1.col4, t1.col5
FROM tablename t1 INNER JOIN (SELECT col1, col2, col3, MIN(col4) as m_col4
FROM tablename
GROUP BY col1, col2, col3) s
ON t1.col1=s.col1
AND t1.col2=s.col2
AND t1.col3=s.col3
AND t1.col4=s.m_col4
GROUP BY
t1.col1, t1.col2, t1.col3, t1.col4
nhưng điều này đang bắt đầu phức tạp hơn.
Kết luận
Theo nguyên tắc chung, không có cách chính xác để chuyển đổi truy vấn Postgresql thành truy vấn MySQL, nhưng có rất nhiều cách giải quyết, truy vấn kết quả có thể đơn giản như truy vấn ban đầu hoặc có thể trở nên rất phức tạp, nhưng nó phụ thuộc vào chính truy vấn.