Truy vấn của bạn là cú pháp hoàn toàn hợp pháp, bạn có thể sắp xếp theo các cột không có trong lựa chọn.
- Demo làm việc với MySQL
- Bản trình diễn làm việc với SQL Server
- Bản trình diễn làm việc với Postgresql
- Bản trình diễn làm việc với SQLite
- Bản trình diễn làm việc với Oracle
Nếu bạn cần các thông số kỹ thuật đầy đủ về thứ tự hợp pháp, trong SQL Standard 2003, nó có một danh sách dài các câu lệnh về những gì thứ tự nên và không nên chứa, (02-Foundation, trang 415, phần 7.13
Tôi nghĩ rằng sự nhầm lẫn của bạn có thể phát sinh từ việc chọn và / hoặc sắp xếp theo các cột không có trong nhóm theo hoặc sắp xếp theo các cột không có trong lựa chọn khi sử dụng phân biệt.
Cả hai đều có cùng một vấn đề cơ bản và MySQL là duy nhất theo hiểu biết của tôi cho phép.
Vấn đề là ở đây, khi sử dụng nhóm theo hoặc phân biệt, bất kỳ cột nào không có trong cả hai đều không cần thiết, vì vậy sẽ không quan trọng nếu chúng có nhiều giá trị khác nhau trên các hàng vì chúng không bao giờ cần thiết. Hãy tưởng tượng tập dữ liệu đơn giản này:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
3 | B | Y |
Nếu bạn viết:
SELECT DISTINCT Column1
FROM T;
Bạn sẽ nhận được
Column1
---------
A
B
Nếu sau đó bạn thêm ORDER BY Column2
, bạn sẽ sử dụng cột nào trong số hai cột2 để sắp xếp A theo, X hoặc Z? Cách chọn giá trị cho cột 2 không mang tính xác định.
Điều tương tự cũng áp dụng cho việc chọn các cột không có trong nhóm theo. Để đơn giản hóa mọi thứ, chỉ cần tưởng tượng hai hàng đầu tiên của bảng trước:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
Trong MySQL, bạn có thể viết
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1;
Điều này thực sự phá vỡ Tiêu chuẩn SQL, nhưng nó hoạt động trong MySQL, tuy nhiên vấn đề là nó không xác định được, kết quả:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
Không đúng hơn hoặc ít hơn
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
Vì vậy, những gì bạn đang nói là cung cấp cho tôi một hàng cho mỗi giá trị riêng biệt của Column1
, mà cả hai bộ kết quả đều thỏa mãn, vậy làm cách nào để biết bạn sẽ nhận được bộ nào? Vâng, bạn không, có vẻ là một quan niệm sai lầm khá phổ biến mà bạn có thể thêm và ORDER BY
để ảnh hưởng đến kết quả, ví dụ như truy vấn sau:
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1
ORDER BY ID DESC;
Sẽ đảm bảo rằng bạn nhận được kết quả sau:
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
vì ORDER BY ID DESC
, tuy nhiên điều này không đúng ( như được minh họa ở đây
).
Tài liệu MySQL trạng thái:
Vì vậy, mặc dù bạn có một đơn đặt hàng theo thứ tự này không áp dụng cho đến khi một hàng cho mỗi nhóm đã được chọn và một hàng này là không xác định.
SQL-Standard không cho phép các cột trong danh sách chọn không có trong GROUP BY hoặc một hàm tổng hợp, tuy nhiên, các cột này phải phụ thuộc về mặt chức năng vào một cột trong GROUP BY. Từ SQL-2003-Standard (5WD-02-Foundation-2003-09 - trang 346) - http ://www.wiscorp.com/sql_2003_standard.zip
Ví dụ:ID trong bảng mẫu là KHÓA CHÍNH, vì vậy chúng tôi biết nó là duy nhất trong bảng, do đó, truy vấn sau tuân theo tiêu chuẩn SQL và sẽ chạy trong MySQL và không thành công trong nhiều DBMS hiện tại (Tại thời điểm viết bài Postgresql là DBMS gần nhất mà tôi biết để triển khai đúng tiêu chuẩn - Ví dụ ở đây ):
SELECT ID, Column1, Column2
FROM T
GROUP BY ID;
Vì ID là duy nhất cho mỗi hàng, chỉ có thể có một giá trị của Column1
cho mỗi ID, một giá trị của Column2
không có sự mơ hồ về những gì sẽ trả lại cho mỗi hàng.