Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

MySQL: SELECT DISTINCT kết hợp COUNT (đếm số lần xuất hiện)

Để lấy danh sách giá trị duy nhất (DISTINCT) kèm theo số lần xuất hiện của mỗi giá trị, bạn dùng GROUP BY kết hợp hàm tập hợp COUNT(*).

Cú pháp

SELECT ten_cot, COUNT(*) AS so_lan_xuat_hien
FROM ten_bang
GROUP BY ten_cot;

Ví dụ minh họa

1. Tạo bảng

CREATE TABLE selectDistinct_CountDemo (
    Id INT NOT NULL AUTO_INCREMENT,
    Name VARCHAR(10),
    AppearanceId INT,
    PRIMARY KEY(Id)
);

2. Chèn dữ liệu (Larry xuất hiện 4 lần)

INSERT INTO selectDistinct_CountDemo(Name, AppearanceId) VALUES
('Larry', 1), ('John', 2), ('Larry', 3),
('Larry', 10), ('Carol', 11), ('Larry', 15);

3. Xem dữ liệu gốc

SELECT * FROM selectDistinct_CountDemo;

Kết quả:

+----+-------+--------------+
| Id | Name  | AppearanceId |
+----+-------+--------------+
| 1  | Larry | 1            |
| 2  | John  | 2            |
| 3  | Larry | 3            |
| 4  | Larry | 10           |
| 5  | Carol | 11           |
| 6  | Larry | 15           |
+----+-------+--------------+

4. Truy vấn: DISTINCT + COUNT

SELECT Name, COUNT(*) AS TotalAppearance
FROM selectDistinct_CountDemo
GROUP BY Name;

Kết quả:

+-------+-----------------+
| Name  | TotalAppearance |
+-------+-----------------+
| Larry | 4               |
| John  | 1               |
| Carol | 1               |
+-------+-----------------+

Các biến thể hữu ích

1. Sắp xếp theo số lần giảm dần

SELECT Name, COUNT(*) AS cnt
FROM selectDistinct_CountDemo
GROUP BY Name
ORDER BY cnt DESC;

2. Chỉ lấy giá trị xuất hiện > 1 lần (trùng lặp)

SELECT Name, COUNT(*) AS cnt
FROM selectDistinct_CountDemo
GROUP BY Name
HAVING COUNT(*) > 1;

3. Đếm DISTINCT trên cột khác (ví dụ: số AppearanceId riêng biệt per Name)

SELECT Name, COUNT(DISTINCT AppearanceId) AS unique_appearances
FROM selectDistinct_CountDemo
GROUP BY Name;

4. Nhóm theo nhiều cột

SELECT Name, Age, COUNT(*) 
FROM bang 
GROUP BY Name, Age;

⚠️ Sai lầm thường gặp

Sai: DISTINCT + COUNT(*) không cần GROUP BY

-- KHÔNG HỢP LỆ trong hầu hết SQL (MySQL ONLY_FULL_GROUP_BY sẽ báo lỗi)
SELECT DISTINCT Name, COUNT(*) FROM bang;

Đúng: GROUP BY

SELECT Name, COUNT(*) FROM bang GROUP BY Name;

Hiệu năng & Index

  • Tạo index trên cột GROUP BY: CREATE INDEX idx_name ON bang(Name);
  • COUNT(*) đếm tất cả hàng (kể NULL)
  • COUNT(cot) chỉ đếm hàng có cot NOT NULL
  • COUNT(DISTINCT cot) đếm giá trị duy nhất (chậm hơn, cần sort/hash)

Mở rộng: Window Function (MySQL 8.0+)

SELECT DISTINCT Name, 
    COUNT(*) OVER (PARTITION BY Name) AS TotalAppearance
FROM selectDistinct_CountDemo;

Trả về cùng số hàng như bảng gốc nhưng có cột count cho mỗi nhóm.