Mục đích
Sử dụng DISTINCT kết hợp GROUP BY và HAVING COUNT(*) > N để lọc các giá trị xuất hiện nhiều hơn ngưỡng cho trước.
Cú pháp
SELECT DISTINCT yourColumnName, COUNT(yourColumnName)
FROM yourTableName
WHERE yourColumnName LIKE 'J%'
GROUP BY yourColumnName
HAVING COUNT(*) > 1
ORDER BY yourColumnName;
Ví dụ hoàn chỉnh
1. Tạo bảng
CREATE TABLE DemoTable1500 (
Name VARCHAR(20)
);
2. Chèn dữ liệu
INSERT INTO DemoTable1500 VALUES ('Adam');
INSERT INTO DemoTable1500 VALUES ('John');
INSERT INTO DemoTable1500 VALUES ('Mike');
INSERT INTO DemoTable1500 VALUES ('John');
INSERT INTO DemoTable1500 VALUES ('Jace');
INSERT INTO DemoTable1500 VALUES ('Jace');
INSERT INTO DemoTable1500 VALUES ('Jackie');
3. Xem toàn bộ dữ liệu
SELECT * FROM DemoTable1500;
Kết quả
+--------+
| Name |
+--------+
| Adam |
| John |
| Mike |
| John |
| Jace |
| Jace |
| Jackie |
+--------+
4. Truy vấn: Tên bắt đầu bằng 'J' và xuất hiện > 1 lần
SELECT DISTINCT Name, COUNT(Name)
FROM DemoTable1500
WHERE Name LIKE 'J%'
GROUP BY Name
HAVING COUNT(*) > 1
ORDER BY Name;
Kết quả
+------+-------------+
| Name | count(Name) |
+------+-------------+
| Jace | 2 |
| John | 2 |
+------+-------------+
Giải thích các mệnh đề
WHERE Name LIKE 'J%': Lọc trước các hàng tên bắt đầu bằng J (giảm dữ liệu cho GROUP BY).GROUP BY Name: Gom nhóm các hàng cùng tên.COUNT(Name): Đếm số hàng trong mỗi nhóm.HAVING COUNT(*) > 1: Lọc nhóm **sau khi gom**, chỉ giữ nhóm có count > 1.DISTINCT Name: Ở đây thừa vì GROUP BY đã đảm bảo duy nhất, nhưng viết cho rõ ý đồ.ORDER BY Name: Sắp xếp kết quả.
WHERE vs HAVING
| Đặc điểm | WHERE | HAVING |
|---|---|---|
| Áp dụng cho | Hàng riêng lẻ (trước GROUP BY) | Nhóm (sau GROUP BY) |
| Có thể dùng aggregate | Không | Có (COUNT, SUM...) |
| Ví dụ | Name LIKE 'J%' | COUNT(*) > 1 |
Lưu ý hiệu năng
- Index trên cột
Namegiúp WHERE và GROUP BY nhanh hơn. - Tránh
SELECT DISTINCT *trên bảng lớn. - MySQL 8.0+ hỗ trợ CTE (WITH) để viết rõ ràng hơn.