2016-01-09 16 views
7

Có vẻ như trong phiên bản 5.7 của MySQL, họ đã thêm một điều khó chịu (hoặc vẫn là) một headache thực cho những người xử lý SQL Server.SELECT DISTINCT và ORDER BY trong MySQL

Điều này là: MySQL ném lỗi, khi bạn cố gắng SELECT DISTINCT hàng cho một nhóm cột và muốn ORDER BY một nhóm cột khác. Trước đây, trong phiên bản 5.6 và thậm chí trong một số phiên bản 5.7, bạn có thể làm điều này, nhưng bây giờ nó bị cấm (ít nhất là theo mặc định).

Tôi hy vọng có một số cấu hình, một số biến mà chúng tôi có thể đặt để làm cho nó hoạt động. Nhưng tiếc là tôi không biết rằng biến khó chịu. Tôi hy vọng ai đó biết điều đó.

EDIT

Đây là một số truy vấn điển hình trong trường hợp của tôi mà làm việc theo nghĩa đen trong nhiều năm (cho đến khi xây dựng mới nhất của MySQL 5.7):

SELECT DISTINCT a.attr_one, a.attr_two, a.attr_three, b.attr_four FROM table_one a 
LEFT JOIN table_two b ON b.some_idx = a.idx 
ORDER BY b.id_order 

Và, quả thật vậy, nếu bây giờ tôi bao gồm b.id_order đến phần SELECT (như MySQL gợi ý làm), sau đó những gì tôi sẽ nhận được, sẽ là rác rưởi.

+0

Đây có phải là truy vấn thực tế? – Strawberry

+0

Vâng, đó là một truy vấn thế giới thực. – Jacobian

Trả lời

7

Trong hầu hết các trường hợp, một mệnh đề DISTINCT có thể được coi là một trường hợp đặc biệt của GROUP BY. Ví dụ,

ONLY_FULL_GROUP_BY

MySQL 5.7.5 và lên dụng cụ phát hiện sự phụ thuộc chức năng. Nếu chế độ SQL ONLY_FULL_GROUP_BY Chế độ SQL được bật (theo mặc định), MySQL sẽ từ chối truy vấn danh sách lựa chọn, điều kiện HAVING hoặc danh sách ORDER BY tham chiếu đến các cột không được phân tách không có tên trong mệnh đề GROUP BY. về họ. (Trước 5.7.5, MySQL không phát hiện sự phụ thuộc chức năng và ONLY_FULL_GROUP_BY không được kích hoạt theo mặc định. Đối với một mô tả về trước 5.7.5 hành vi)

Nếu ONLY_FULL_GROUP_BY bị vô hiệu hóa, một phần mở rộng MySQL đến việc sử dụng SQL tiêu chuẩn của GROUP BY cho phép danh sách lựa chọn, điều kiện HAVING hoặc danh sách ORDER BY để tham chiếu đến các cột không được phân tách ngay cả khi các cột không phụ thuộc vào chức năng trên các cột GROUP BY. Điều này làm cho MySQL chấp nhận truy vấn trước đó. Trong trường hợp này, máy chủ được tự do chọn bất kỳ giá trị nào từ mỗi nhóm, do đó, trừ khi chúng giống nhau, các giá trị được chọn không xác định, có thể không phải là những gì bạn muốn. Hơn nữa, việc lựa chọn các giá trị từ mỗi nhóm không thể bị ảnh hưởng bằng cách thêm mệnh đề ORDER BY. Phân loại tập hợp kết quả xảy ra sau khi các giá trị đã được chọn, và ORDER BY không ảnh hưởng đến giá trị nào trong mỗi nhóm mà máy chủ chọn. Vô hiệu hóa ONLY_FULL_GROUP_BY hữu ích chủ yếu khi bạn biết rằng, do một số thuộc tính của dữ liệu, tất cả các giá trị trong mỗi cột không được phân tách không được đặt tên trong GROUP BY đều giống nhau cho mỗi nhóm.

để biết thêm http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by

cho câu trả lời đặc biệt

SELECT DISTINCT attr_one, 
      attr_two, 
      attr_three, 
      attr_four 
FROM 
    (SELECT a.attr_one, 
     a.attr_two, 
     a.attr_three, 
     b.attr_four 
    FROM table_one a 
    LEFT JOIN table_two b ON b.some_idx = a.idx 
    ORDER BY b.id_order) tmp 
+2

Tôi biết điều đó. Tôi đã vô hiệu hóa 'ONLY_FULL_GROUP_BY' bằng cách đặt' sql_mode' thành '" "' trong 'my.cnf', nhưng vấn đề này với' DISTINCT' và 'ORDER BY' không được giải quyết. – Jacobian

+0

Phiên bản sql của bạn là gì, bạn đã thử max_sort_length chưa? – developerCK

+0

Phiên bản là 5.7.10. Bạn có ý gì khi thử biến này? – Jacobian

0

Tôi đã đọc bài đăng trên liên kết bạn đã đề cập và có vẻ như đã được giải thích rõ ràng về lý do lỗi được ném và cách tránh lỗi.

Trong trường hợp của bạn, bạn có thể muốn thử những điều sau đây (không kiểm tra tất nhiên):

SELECT a.attr_one, a.attr_two, a.attr_three, b.attr_four 
FROM table_one a 
LEFT JOIN table_two b ON b.some_idx = a.idx 
GROUP BY a.attr_one, a.attr_two, a.attr_three, b.attr_four 
ORDER BY max(b.id_order) 

Bạn nên chọn xem có sử dụng ORDER BY max(b.id_order), hoặc ORDER BY min(b.id_order) hoặc chức năng tổng hợp khác

+0

Nó sẽ không hoạt động trong MySQL. Nếu tôi không nhầm lẫn trong MySQL, không có gì đảm bảo rằng tập kết quả sẽ là 'ORDER'ed đầu tiên và sau đó là' GROUP'ed 'BY'. – Jacobian

+0

Hoặc, như developerCK nói, "Hơn nữa, việc lựa chọn các giá trị từ mỗi nhóm không thể bị ảnh hưởng bởi việc thêm mệnh đề ORDER BY. Kết quả sắp xếp xảy ra sau khi các giá trị đã được chọn, và ORDER BY không ảnh hưởng đến giá trị nào trong mỗi nhóm máy chủ chọn. " – Jacobian