學生成績表 student(score),需統計各分數段人數:
SELECT '60分以下' AS `type`, COUNT(*) FROM student WHERE score < 60
UNION ALL
SELECT '60-70分', COUNT(*) FROM student WHERE score >= 60 AND score < 70
UNION ALL
SELECT '70-80分', COUNT(*) FROM student WHERE score >= 70 AND score < 80
UNION ALL
SELECT '80-90分', COUNT(*) FROM student WHERE score >= 80 AND score < 90
UNION ALL
SELECT '90分以上', COUNT(*) FROM student WHERE score >= 90;
+-----------+----------+
| type | COUNT(*) |
+-----------+----------+
| 60分以下 | 1 |
| 60-70分 | 1 |
| 70-80分 | 2 |
| 80-90分 | 1 |
| 90分以上 | 3 |
+-----------+----------+
SELECT
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS '60分以下',
SUM(CASE WHEN score >= 60 AND score < 70 THEN 1 ELSE 0 END) AS '60-70分',
SUM(CASE WHEN score >= 70 AND score < 80 THEN 1 ELSE 0 END) AS '70-80分',
SUM(CASE WHEN score >= 80 AND score < 90 THEN 1 ELSE 0 END) AS '80-90分',
SUM(CASE WHEN score >= 90 THEN 1 ELSE 0 END) AS '90分以上'
FROM student;
優點:只掃描一次表,大數據量下性能遠優於 UNION ALL 多次掃描。
若分段邏輯常變,建議建立 分段配置表 score_range(id, label, min_score, max_score),應用層動態拼接 SQL 或使用存儲過程循環查詢。
UNION ALL 寫法直觀易維護。CASE WHEN 單次聚合,配合索引 INDEX(score) 效果最佳。