MySQL Mệnh đề GROUP BY và HAVING kèm ví dụ

⚡ Tóm tắt thông minh

Mệnh đề SQL GROUP BY và HAVING biến các hàng chi tiết thành báo cáo tóm tắt. GROUP BY gộp các hàng có cùng giá trị thành một hàng duy nhất cho mỗi nhóm, trong khi HAVING lọc các nhóm đó sau khi các hàm tổng hợp như COUNT đã được áp dụng.

  • 📊 Mục đích cốt lõi: Lệnh GROUP BY nhóm các hàng có giá trị giống nhau và trả về một hàng duy nhất cho mỗi mục được nhóm.
  • 🧩 Nhóm cột đơnping: Nhómping Bảng thành viên theo giới tính thu gọn chín hàng thành hai hàng, một hàng dành cho Nữ và một hàng dành cho Nam.
  • 🔗 Nhóm nhiều cộtping: Nhómping Trên hai cột, một hàng được coi là duy nhất khi một trong hai giá trị khác nhau, vì vậy chỉ những bản sao chính xác mới được thu gọn.
  • 🧮 Ghép cặp tổng hợp: ĐẾM, TỔNG, AVGCác hàm MIN và MAX tính toán một giá trị cho mỗi nhóm, từ đó tạo ra báo cáo tóm tắt.
  • 🚦 CÓ so với Ở ĐÂU: WHERE lọc các hàng trước nhómpingSau đó, HAVING lọc các nhóm và chỉ HAVING mới chấp nhận kết quả tổng hợp.
  • ⚠️ Cảnh báo Chế độ Nghiêm ngặt: Trong tùy chọn ONLY_FULL_GROUP_BY, mọi cột được chọn phải được nhóm hoặc bao bọc trong một hàm tổng hợp.

Mệnh đề SQL GROUP BY và HAVING

Mệnh đề GROUP BY trong SQL là gì?

Mệnh đề GROUP BY là một lệnh SQL được sử dụng để nhóm các hàng có cùng giá trịNó được viết bên trong câu lệnh SELECT và thường được sử dụng cùng với các hàm tổng hợp để tạo ra các báo cáo tóm tắt từ cơ sở dữ liệu.

Đó chính là chức năng của nó: nó tóm tắt dữ liệu được lưu trữ trong cơ sở dữ liệu. Các truy vấn chứa mệnh đề GROUP BY được gọi là truy vấn nhóm và chúng trả về một hàng duy nhất cho mỗi mục được nhóm.

NHÓM SQL THEO Cú pháp

Giờ thì mục đích của mệnh đề đã rõ ràng, hãy xem xét cú pháp của một truy vấn nhóm cơ bản.

SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];

tại ĐÂY

  • "Câu lệnh SELECT…“là tiêu chuẩn” SQL CHỌN truy vấn lệnh.
  • "NHÓM THEO tên_cột1" là mệnh đề thực hiện việc nhóm."ping dựa trên column_name1.
  • "[, tên_cột_2, …]” là tùy chọn và đại diện cho các tên cột khác khi nhómping Việc này được thực hiện trên nhiều cột.
  • "[ĐANG có điều kiện]Tham số ” là tùy chọn và được sử dụng để giới hạn các hàng bị ảnh hưởng bởi mệnh đề GROUP BY. Nó tương tự như Mệnh đề WHEREngoại trừ việc nó được áp dụng sau nhómping.

Nhómping Sử dụng một cột duy nhất

Cách nhanh nhất để thấy tác dụng của mệnh đề SQL GROUP BY là so sánh một truy vấn không nhóm với một truy vấn có nhóm. Hãy bắt đầu với một truy vấn đơn giản trả về tất cả các mục giới tính trong bảng thành viên.

SELECT `gender` FROM `members`;
giới
Nữ
Nữ
Nam
Nữ
Nam
Nam
Nam
Nam
Nam

Truy vấn trả về chín hàng, và mỗi giá trị đều lặp lại. Giả sử chúng ta muốn các giá trị duy nhất cho giới tính. Truy vấn bên dưới sẽ thêm mệnh đề GROUP BY.

SELECT `gender` FROM `members` GROUP BY `gender`;

Thực thi đoạn script trên trong MySQL Workbench so với myflixdb cung cấp cho chúng ta kết quả sau.

giới
Nữ
Nam

Lưu ý rằng chỉ có hai hàng được trả về, vì bảng chỉ chứa hai loại giới tính. Mệnh đề GROUP BY đã nhóm tất cả các thành viên "Nam" lại với nhau và trả về một hàng duy nhất cho họ, và nó cũng làm tương tự với các thành viên "Nữ".

Nhómping Sử dụng nhiều cột

Nhómping Việc chỉ sử dụng một cột thường quá sơ sài đối với một báo cáo thực tế. Lệnh GROUP BY chấp nhận một danh sách các cột được phân tách bằng dấu phẩy, và sự kết hợp các giá trị của chúng sẽ xác định từng nhóm.

Giả sử chúng ta muốn có một danh sách các giá trị category_id của phim và năm phát hành tương ứng của các bộ phim đó. Trước tiên, hãy quan sát kết quả của truy vấn đơn giản này.

SELECT `category_id`, `year_released` FROM `movies`;
Thể loại ID năm_phát hành
1 2011
2 2008
NULL 2008
NULL 2010
8 2007
6 2007
6 2007
8 2005
NULL 2012
7 1920
8 NULL
8 1920

Các hàng được tô sáng cho thấy kết quả chứa các bản ghi trùng lặp. Thực hiện cùng một truy vấn với mệnh đề GROUP BY sẽ loại bỏ chúng.

SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;

Thực thi đoạn script trên trong MySQL Việc chạy lệnh Workbench trên cơ sở dữ liệu myflixdb cho ra các kết quả như hình bên dưới.

Thể loại ID năm_phát hành
NULL 2008
NULL 2010
NULL 2012
1 2011
2 2008
6 2007
7 1920
8 1920
8 2005
8 2007

Mệnh đề GROUP BY hoạt động trên cả category_id và year_released để xác định. độc đáo hàng. Hai hàng trùng lặp cho hạng mục 6 năm 2007 đã được gộp lại thành một.

Quy tắc của ngón tay cái: Nếu mã định danh mục giống nhau nhưng năm phát hành khác nhau, hàng đó được coi là duy nhất. Nếu mã định danh mục và năm phát hành giống nhau ở nhiều hơn một hàng, các hàng đó được coi là trùng lặp và chỉ một trong số chúng được hiển thị.

Nhómping và các hàm tổng hợp

Việc loại bỏ các phần tử trùng lặp rất hữu ích, nhưng sức mạnh thực sự của việc nhóm...ping xuất hiện khi nó được ghép nối với Chức năng tổng hợpHàm tổng hợp tính toán một giá trị cho mỗi nhóm: COUNT đếm số hàng, SUM cộng các giá trị, và AVG, MIN và MAX mô tả độ phân tán.

Giả sử chúng ta muốn tính tổng số thành viên nam và nữ trong cơ sở dữ liệu. Đoạn mã dưới đây sẽ thực hiện điều đó.

SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;

Thực thi đoạn script trên trong MySQL Việc chạy lệnh Workbench trên cơ sở dữ liệu myflixdb cho chúng ta các kết quả sau.

giới ĐẾM(`số_thành_viên`)
Nữ 3
Nam 6

Các hàng được nhóm theo từng giá trị giới tính riêng biệt, và số lượng hàng bên trong mỗi nhóm được đếm bằng hàm tổng hợp COUNT. Chín bản ghi thành viên được thu gọn thành hai hàng tóm tắt.

Giới hạn kết quả truy vấn bằng cách sử dụng mệnh đề HAVING

NhómpingKhông phải lúc nào cũng cần điều kiện cho mọi hàng trong bảng. Đôi khi báo cáo phải được giới hạn theo một tiêu chí nhất định, và đó là nhiệm vụ của mệnh đề HAVING.

Giả sử chúng ta muốn biết tất cả các năm phát hành của phim thuộc danh mục có ID 8. Đoạn mã bên dưới sẽ thực hiện điều đó.

SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;

Thực thi đoạn script trên trong MySQL Việc chạy lệnh Workbench trên cơ sở dữ liệu myflixdb cho ra các kết quả như hình bên dưới.

id phim tiêu đề Giám đốc năm_phát hành Thể loại ID
9 Honey mooners John Schultz 2005 8
5 Những cô gái nhỏ của bố NULL 2007 8

Chỉ những phim có mã số danh mục 8 mới được giữ lại theo điều kiện HAVING.

Cảnh báo: MySQL Từ phiên bản 5.7 trở lên, chế độ ONLY_FULL_GROUP_BY được bật mặc định, và ở chế độ đó, câu lệnh SELECT * với mệnh đề GROUP BY sẽ bị từ chối vì movie_id, title và director không được nhóm hoặc tổng hợp. Trong môi trường sản xuất, hãy đặt tên rõ ràng cho các cột được nhóm, ví dụ: SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;

WHERE so với HAVING so với GROUP BY so với ORDER BY

Người mới bắt đầu thường nhầm lẫn bốn mệnh đề này, bởi vì tất cả chúng đều hình thành nên tập hợp kết quả. Sự khác biệt nằm ở chỗ khi nào MySQL Cách thức thực hiện như sau: Mệnh đề WHERE chạy trước khi các hàng được nhóm lại, HAVING chạy sau và ORDER BY chạy cuối cùng.

Khoản Những gì nó Khi nó chạy Chấp nhận các hàm tổng hợp
Ở ĐÂU Lọc từng hàng riêng lẻ trước khi lọc theo nhóm.ping. Trước khi nhóm theo Không
NHÓM THEO Gộp các hàng có cùng giá trị thành một hàng duy nhất cho mỗi nhóm. Sau WHERE Không áp dụng
ĐANG CÓ Lọc các nhóm được tạo bởi mệnh đề GROUP BY. Sau khi nhóm theo Vâng, ví dụ HAVING COUNT(*) > 2
ĐẶT BỞI Sắp xếp các hàng còn lại sau khi các điều khoản trước đó được thực thi. Trang cuối Vâng, một bí danh tổng hợp có thể được sắp xếp.

Hậu quả thực tế là về hiệu năng. Việc lọc bằng mệnh đề WHERE loại bỏ các hàng trước khi nhóm được xử lý.ping Công việc bắt đầu, vì vậy một điều kiện không phụ thuộc vào kết quả tổng hợp thì nên dùng mệnh đề WHERE thay vì HAVING.

Câu Hỏi Thường Gặp

Đúng vậy. Lệnh GROUP BY tự nó trả về một hàng cho mỗi giá trị duy nhất, giúp loại bỏ các giá trị trùng lặp tương tự như lệnh SELECT DISTINCT. Các hàm tổng hợp chỉ cần thiết khi mỗi nhóm cần một con số được tính toán.

Lỗi này xuất hiện khi cột được chọn không nằm trong mệnh đề GROUP BY cũng như không được bao bọc trong hàm tổng hợp. MySQL Không thể quyết định giá trị nào của cột đó sẽ được hiển thị cho nhóm, vì vậy nó từ chối truy vấn.

COUNT(*) đếm tất cả các hàng trong nhóm. COUNT(column) chỉ đếm các hàng mà cột đó không phải là NULLVì vậy, hai con số này sẽ khác nhau bất cứ khi nào cột đó chứa các giá trị bị thiếu.

Đúng vậy. Trợ lý AI tích hợp trong các công cụ như... MySQL Workbench Chuyển đổi yêu cầu như "số thành viên theo giới tính" thành truy vấn nhóm. Kiểm tra nhómping các cột của riêng bạn, bởi vì một nhóm saiping Tạo ra các tổng số trông có vẻ hợp lý nhưng lại không chính xác.

Thường thì đúng vậy. Các trợ lý truy vấn AI sẽ chỉ ra những nguyên nhân điển hình như... THAM GIA nhân các hàng trước nhómpinghoặc một bộ lọc được đặt trong HAVING thay vì WHERE. Quyết định cuối cùng vẫn thuộc về người nắm rõ dữ liệu.

Tóm tắt bài viết này với: