PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chuyển đổi các truy vấn SELECT DISTINCT ON từ Postgresql sang MySQL

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. postgresql:kiểu dữ liệu cho thông báo md5?

  2. Java Enums, JPA và Postgres enums - Làm cách nào để làm cho chúng hoạt động cùng nhau?

  3. Mac + virtualenv + pip + postgresql =Lỗi:không tìm thấy tệp thực thi pg_config

  4. LỖI:không thể truy cập tệp “$ libdir / plpython2” - LỖI:không thể truy cập tệp “$ libdir / plpython3”

  5. Cách thoát chuỗi khi khớp mẫu trong PostgreSQL