DISTINCT:按數據**存儲/讀取順序**返回(無序保證)GROUP BY:默認按分組列**升序排序**返回(隱式 ORDER BY)-- 測試數據
name | age | height
c | 2 | 123
c | 2 | 456
b | 20 | 222
-- DISTINCT 多列:只有「所有列值完全相同」才去重
SELECT DISTINCT name, age FROM t; -- 返回 (c,2) (b,20) ✅
-- GROUP BY 多列:按多列組合分組
SELECT name, age, SUM(height) FROM t GROUP BY name, age;
-- 返回 (b,20,222) (c,2,579) ✅
SELECT name, age, SUM(height) AS n FROM t GROUP BY name, age HAVING n > 500;
-- 僅返回 (c,2,579)
-- 歌曲統計:按歌曲+歌手分組,取出現次數 TOP 10
SELECT songname, singerid, COUNT(*) AS n
FROM t_song
GROUP BY songname, singerid
HAVING n > 1
ORDER BY n DESC, songid ASC
LIMIT 10;
-- LIMIT 5 同理:先分組/聚合/排序,再取前 5 行
-- 證據:n 列值均 > 10,說明 LIMIT 在聚合後生效
SELECT COUNT(DISTINCT songid) FROM feedback;
SELECT COUNT(DISTINCT(songid)) FROM feedback; -- 兩種寫法結果相同
MAX(col):忽略 NULL,取非空最大值(字符串按字典序)SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...
將 SELECT col, COUNT(*) FROM t GROUP BY col 簡化為 SELECT COUNT(*) FROM t GROUP BY col 會報錯:
Unknown column 'new_time' in 'order clause'
-- 因為外層 SELECT 丟失了 GROUP BY 依賴的列/別名
**修正**:保持原 SELECT 列表,或用子查詢包裹。
| 場景 | 推薦寫法 | 關鍵點 |
|---|---|---|
| 單列去重,有索引 | GROUP BY col | 性能最優,語義清晰 |
| 多列組合去重 | DISTINCT col1, col2 / GROUP BY col1, col2 | 等價,按習慣選 |
| 按 A 去重保留 B 第一行 | 窗口函數 ROW_NUMBER() / 子查詢 MIN(id) | DISTINCT/GROUP BY 無法直接實現 |
| 統計去重數 | COUNT(DISTINCT col) | 標準寫法 |
| 分組後過濾 | HAVING agg > val | WHERE 不能用聚合 |
| 分組後排序分頁 | ORDER BY ... LIMIT ... | LIMIT 作用於最終結果集 |
熟練掌握 DISTINCT/GROUP BY/HAVING/LIMIT 的組合語義,是寫出高性能、正確聚合查詢的基石。