Để đếm số lần xuất hiện của nhiều giá trị khác nhau trên cùng một cột và hiển thị từng loại đếm trên một cột riêng biệt (pivot/crosstab), MySQL dùng SUM() kết hợp với biểu thức boolean (col = 'value' trả về 1/0).
Ví dụ minh họa
Tạo bảng màu yêu thích:
mysql> CREATE TABLE DemoTable1452 (
FavouriteColor VARCHAR(50)
);
Chèn dữ liệu:
mysql> INSERT INTO DemoTable1452 VALUES ('Red');
mysql> INSERT INTO DemoTable1452 VALUES ('Yellow');
mysql> INSERT INTO DemoTable1452 VALUES ('Yellow');
mysql> INSERT INTO DemoTable1452 VALUES ('Yellow');
mysql> INSERT INTO DemoTable1452 VALUES ('Blue');
mysql> INSERT INTO DemoTable1452 VALUES ('Blue');
mysql> INSERT INTO DemoTable1452 VALUES ('Red');
Dữ liệu (7 hàng):
mysql> SELECT * FROM DemoTable1452;
+----------------+ | FavouriteColor | +----------------+ | Red | | Yellow | | Yellow | | Yellow | | Blue | | Blue | | Red | +----------------+
Đếm từng màu và hiển thị mỗi loại một cột
mysql> SELECT
SUM(FavouriteColor = 'Red') AS NumberOfRedColor,
SUM(FavouriteColor = 'Yellow') AS NumberOfYellowColor,
SUM(FavouriteColor = 'Blue') AS NumberOfBlueColor
FROM DemoTable1452;
Kết quả (1 hàng, 3 cột):
+------------------+---------------------+-------------------+ | NumberOfRedColor | NumberOfYellowColor | NumberOfBlueColor | +------------------+---------------------+-------------------+ | 2 | 3 | 2 | +------------------+---------------------+-------------------+
Giải thích kỹ thuật
- Trong MySQL, biểu thức so sánh
FavouriteColor = 'Red'trả về1(TRUE) hoặc0(FALSE). SUM()cộng dồn các 1/0 → chính là số lần xuất hiện.- Không cần
GROUP BYvì muốn gom toàn bảng thành 1 hàng.
So sánh với GROUP BY (dạng dài - long format)
-- Dạng dài: mỗi loại một hàng SELECT FavouriteColor, COUNT(*) AS Count FROM DemoTable1452 GROUP BY FavouriteColor;
+----------------+-------+ | FavouriteColor | Count | +----------------+-------+ | Blue | 2 | | Red | 2 | | Yellow | 3 | +----------------+-------+
Dạng rộng (wide format / pivot) như ví dụ chính thường dùng cho: báo cáo dashboard, xuất Excel, API trả về JSON cho chart.
Mở rộng: Pivot động (Dynamic Pivot)
Nếu không biết trước các giá trị màu, cần xây dựng câu SQL động (dynamic SQL) trong Stored Procedure hoặc ứng dụng:
SELECT GROUP_CONCAT(
DISTINCT CONCAT('SUM(FavouriteColor = ''', FavouriteColor, ''') AS `', FavouriteColor, '`')
) INTO @sql FROM DemoTable1452;
SET @sql = CONCAT('SELECT ', @sql, ' FROM DemoTable1452');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Lưu ý hiệu năng
- Cách
SUM(col = 'val')quét toàn bảng một lần — hiệu quả khi số giá trị đếm ít (≤ 20-50). - Nếu số giá trị lớn, cân nhắc
GROUP BY+ xử lý pivot ở tầng ứng dụng. - Index trên cột
FavouriteColorkhông giúp ích cho truy vấn này (full table scan).