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ợp | Chức năng | Ví dụ |
COUNT() | Đếm số bản ghi | COUNT(*) |
SUM() | Tính tổng | SUM(salary) |
AVG() | Tính trung bình | AVG(price) |
MIN() | Giá trị nhỏ nhất | MIN(age) |
MAX() | Giá trị lớn nhất | MAX(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ả:
department | total_employees |
IT | 2 |
HR | 2 |
Finance | 2 |
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ả:
department | total_salary |
IT | 7000 |
HR | 6700 |
Finance | 9500 |
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ả:
department | avg_salary |
IT | 3500.00 |
HR | 3350.00 |
Finance | 4750.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ả:
department | min_salary | max_salary |
IT | 3000.00 | 4000.00 |
HR | 3200.00 | 3500.00 |
Finance | 4500.00 | 5000.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ả:
department | total_salary |
Finance | 9500 |
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ả:
department | total_salary |
Finance | 9500 |
IT | 7000 |
HR | 6700 |
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ả:
department | age | total_employees |
IT | 25 | 1 |
IT | 28 | 1 |
HR | 30 | 1 |
HR | 27 | 1 |
Finance | 35 | 1 |
Finance | 32 | 1 |
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):
department | total_salary |
IT | 7000 |
HR | 6700 |
Finance | 9500 |
NULL | 23200 |