SQL chuẩn sẽ từ chối truy vấn của bạn vì bạn không thể CHỌN các trường không tổng hợp không thuộc mệnh đề GROUP BY trong một truy vấn tổng hợp
Điều này chính xác, đến năm 1992 .
Nhưng nó rõ ràng là sai, từ năm 2003 trở đi.
Từ tiêu chuẩn SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, từ http ://www.wiscorp.com/ , đoạn-7.12 (đặc tả truy vấn), trang 398 :
- Nếu T là một bảng được nhóm lại, thì G là tập hợp các cột nhóm của T. Trong mỗi ((biểu thức giá trị)) chứa trong ((danh sách chọn)), mỗi tham chiếu cột tham chiếu đến một cột của T sẽ tham chiếu đến một số cột C khác phụ thuộc vào chức năng trên G hoặc sẽ được chứa trong một đối số tổng hợp của một ((đặt đặc điểm kỹ thuật chức năng)) có truy vấn tổng hợp là QS
Bây giờ MYSQL, đã triển khai tính năng này bằng cách cho phép không chỉ cột phụ thuộc vào chức năng trên các cột nhóm nhưng cho phép tất cả các cột . Điều này gây ra một số vấn đề với người dùng không hiểu cách hoạt động của nhóm và nhận được kết quả không xác định mà họ không mong đợi.
Nhưng bạn đúng khi nói rằng MySQL đã thêm một tính năng xung đột với các tiêu chuẩn SQL (mặc dù bạn có vẻ nghĩ điều đó là sai). Nó không hoàn toàn chính xác vì họ đã thêm một tính năng theo tiêu chuẩn SQL nhưng không phải theo cách tốt nhất (giống như cách dễ dàng hơn) nhưng nó xung đột với các tiêu chuẩn mới nhất.
Để trả lời câu hỏi của bạn, lý do cho tính năng MySQL này (phần mở rộng) là tôi cho rằng nó phù hợp với các tiêu chuẩn SQL mới nhất (2003+). Tại sao họ chọn triển khai nó theo cách này (không hoàn toàn tuân thủ), chúng ta chỉ có thể suy đoán.
Như @Quassnoi và @Johan đã trả lời bằng các ví dụ, đó chủ yếu là vấn đề về hiệu suất và khả năng bảo trì. Nhưng không thể dễ dàng thay đổi RDBMS đủ thông minh (loại trừ Skynet) để nhận ra các cột phụ thuộc vào chức năng, vì vậy các nhà phát triển MySQL đã đưa ra lựa chọn:
Chúng tôi (MySQL) cung cấp cho bạn (người dùng MySQL) tính năng này trong các tiêu chuẩn SQL-2003. Nó cải thiện tốc độ trong một số
GROUP BY
truy vấn nhưng có một bắt. Bạn phải cẩn thận (chứ không phải công cụ SQL) đối với các cột trongSELECT
vàHAVING
danh sách phụ thuộc về mặt chức năng vàoGROUP BY
cột. Nếu không, bạn có thể nhận được kết quả không xác định.
Nếu bạn muốn tắt nó, bạn có thể đặt
sql_mode
tớiONLY_FULL_GROUP_BY
.
Tất cả đều có trong Tài liệu MySQL:Tiện ích mở rộng cho GROUP BY
(5.5)
- mặc dù không phải trong từ ngữ ở trên nhưng như trong trích dẫn của bạn (họ thậm chí quên đề cập rằng đó là sự sai lệch so với SQL-2003 tiêu chuẩn trong khi không phải là SQL-92 tiêu chuẩn). Tôi nghĩ rằng loại lựa chọn này là phổ biến trong tất cả các phần mềm, bao gồm cả RDBMS khác. Chúng được tạo ra vì hiệu suất, khả năng tương thích ngược và rất nhiều lý do khác. Oracle có '' is the same as NULL
ví dụ và SQL-Server có lẽ cũng có một số.
Ngoài ra còn có bài đăng blog này của Peter Bouman, nơi lựa chọn của các nhà phát triển MySQL được bảo vệ: Gỡ lỗi NHÓM THEO huyền thoại .
Vào năm 2011, với tư cách là @Mark Byers đã thông báo cho chúng tôi trong một nhận xét (trong một câu hỏi liên quan tại DBA.SE), PostgreSQL 9.1 đã thêm một tính năng mới (ngày phát hành:tháng 9 năm 2011) được thiết kế cho mục đích này. Nó hạn chế hơn việc triển khai của MySQL và gần với tiêu chuẩn hơn.
Sau đó, vào năm 2015, MySQL đã thông báo rằng trong phiên bản 5.7, hành vi được cải thiện để phù hợp với tiêu chuẩn và thực sự nhận ra các phụ thuộc chức năng, (thậm chí còn tốt hơn việc triển khai Postgres). Tài liệu: Xử lý MySQL của GROUP BY
(5,7)
và một bài đăng trên blog khác của Peter Bouman: MySQL 5.7.5:GROUP BY
tôn trọng các phụ thuộc chức năng!