GROUP BY trong MySQL

GROUP BY được sử dụng để nhóm các hàng có cùng giá trị trong một hoặc nhiều cột và thực hiện các phép tính tổng hợp trên từng nhóm.

Cú pháp cơ bản

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name;
  • column_name: Cột cần nhóm dữ liệu.

  • aggregate_function(column_name): Hàm tổng hợp áp dụng trên nhóm.

  • table_name: Tên bảng cần truy vấn.

  • WHERE condition: Điều kiện lọc dữ liệu trước khi nhóm.

  • GROUP BY column_name: Nhóm dữ liệu theo cột.

Các hàm tổng hợp phổ biến sử dụng với GROUP BY

Hàm tổng hợpChức năngVí dụ
COUNT()Đếm số bản ghiCOUNT(*)
SUM()Tính tổngSUM(salary)
AVG()Tính trung bìnhAVG(price)
MIN()Giá trị nhỏ nhấtMIN(age)
MAX()Giá trị lớn nhấtMAX(score)

Ví dụ minh họa

Tạo bảng dữ liệu mẫu

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    department VARCHAR(50),
    salary DECIMAL(10,2),
    age INT
);

INSERT INTO employees (department, salary, age) VALUES
('IT', 3000, 25),
('IT', 4000, 28),
('HR', 3500, 30),
('HR', 3200, 27),
('Finance', 5000, 35),
('Finance', 4500, 32);

GROUP BY với COUNT()

Đếm số nhân viên theo phòng ban

SELECT department, COUNT(*) AS total_employees
FROM employees
GROUP BY department;

Kết quả:

departmenttotal_employees
IT2
HR2
Finance2

GROUP BY với SUM()

Tổng lương theo phòng ban

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department;

Kết quả:

departmenttotal_salary
IT7000
HR6700
Finance9500

GROUP BY với AVG()

Lương trung bình theo phòng ban

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;

Kết quả:

departmentavg_salary
IT3500.00
HR3350.00
Finance4750.00

GROUP BY với MIN() và MAX()

SELECT department, MIN(salary) AS min_salary, MAX(salary) AS max_salary
FROM employees
GROUP BY department;

Kết quả:

departmentmin_salarymax_salary
IT3000.004000.00
HR3200.003500.00
Finance4500.005000.00

GROUP BY kết hợp với HAVING

  • WHERE lọc dữ liệu trước khi nhóm.

  • HAVING lọc dữ liệu sau khi nhóm.

Chỉ lấy những phòng ban có tổng lương lớn hơn 8000

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING total_salary > 8000;

Kết quả:

departmenttotal_salary
Finance9500

GROUP BY kết hợp với ORDER BY

Tổng lương theo phòng ban và sắp xếp giảm dần

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
ORDER BY total_salary DESC;

Kết quả:

departmenttotal_salary
Finance9500
IT7000
HR6700

GROUP BY với nhiều cột

Đếm số nhân viên theo phòng ban và tuổi

SELECT department, age, COUNT(*) AS total_employees
FROM employees
GROUP BY department, age;

Kết quả:

departmentagetotal_employees
IT251
IT281
HR301
HR271
Finance351
Finance321

Lưu ý quan trọng khi sử dụng GROUP BY

Không dùng SELECT các cột không nằm trong GROUP BY, trừ khi sử dụng hàm tổng hợp.
Ví dụ sử dụng sai:

SELECT department, salary
FROM employees
GROUP BY department;

Ví dụ sử dụng đúng:

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department;

Có thể dùng WITH ROLLUP để tính tổng tất cả các nhóm;

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department WITH ROLLUP;

Kết quả (dòng cuối là tổng tất cả các phòng ban):

departmenttotal_salary
IT7000
HR6700
Finance9500
NULL23200