首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL DISTINCT 與 GROUP BY 實戰對比:輸出順序、效率、多列去重、LIMIT 行為與常見錯誤

     編輯:MySQL 綜合教學

輸出順序差異

  • DISTINCT:按數據**存儲/讀取順序**返回(無序保證)
  • GROUP BY:默認按分組列**升序排序**返回(隱式 ORDER BY)

效率本質

  • DISTINCT:讀取所有行 → 去重
  • GROUP BY:讀取行數 ≈ **分組數**(通常遠小於總行數),分組過程中即完成去重
  • **結論**:大數據量下 GROUP 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)  ✅

HAVING 與 LIMIT 實戰

HAVING 過濾聚合結果

SELECT name, age, SUM(height) AS n FROM t GROUP BY name, age HAVING n > 500;
-- 僅返回 (c,2,579)

LIMIT 作用於「分組後結果集」

-- 歌曲統計:按歌曲+歌手分組,取出現次數 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 在聚合後生效

DISTINCT 計數寫法等價

SELECT COUNT(DISTINCT songid) FROM feedback;
SELECT COUNT(DISTINCT(songid)) FROM feedback;  -- 兩種寫法結果相同

聚合函數與 NULL 值處理

  • MAX(col):忽略 NULL,取非空最大值(字符串按字典序)
  • 若組內全 NULL → 返回 NULL

標準子句順序(必背)

SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...

GROUP BY + COUNT 陷阱

將 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 > valWHERE 不能用聚合
分組後排序分頁ORDER BY ... LIMIT ...LIMIT 作用於最終結果集

熟練掌握 DISTINCT/GROUP BY/HAVING/LIMIT 的組合語義,是寫出高性能、正確聚合查詢的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved