首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 查詢某欄位不重複的完整資料列:DISTINCT 進階用法

     編輯:MySQL 資料庫相關知識

問題場景

表 book:

id | author | title
1  | aaa    | AAA
2  | bbb    | BBB
3  | ccc    | CCC
4  | ddd    | DDD
5  | eee    | AAA

需求:依 title 去重,保留完整欄位(如取第一筆或最後一筆)。

SELECT DISTINCT title, author FROM book 仍會回傳 5 筆,因 DISTINCT 作用於所有選取欄位組合。

解法:子查詢 + JOIN 取極值 ID

取每組第一筆(最小 id)

SELECT a.*
FROM book a
RIGHT JOIN (
    SELECT MIN(id) AS id FROM book GROUP BY title
) b ON b.id = a.id
WHERE a.id IS NOT NULL;

取每組最後一筆(最大 id)

SELECT a.*
FROM book a
RIGHT JOIN (
    SELECT MAX(id) AS id FROM book GROUP BY title
) b ON b.id = a.id
WHERE a.id IS NOT NULL;

原理解析

  1. 子查詢 GROUP BY title 取每組極值 id。
  2. 外層 JOIN 回主表撈完整欄位。
  3. RIGHT JOIN 確保即使主表無對應也保留子查詢結果(理論上不會發生)。

MySQL 8.0+ 更優雅寫法:ROW_NUMBER()

WITH ranked AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY title ORDER BY id) AS rn
    FROM book
)
SELECT id, author, title FROM ranked WHERE rn = 1;
  • PARTITION BY title 分組。
  • ORDER BY id 決定取第一筆或最後一筆(DESC 取最後)。
  • 效能優於舊版 JOIN 寫法,語意更清晰。

效能建議

  • 在 title 上建立索引:CREATE INDEX idx_title ON book(title);
  • 若頻繁查詢,考慮物化視圖或應用層快取。
  • 避免 SELECT DISTINCT *,必須明確列出欄位。

常見誤區

錯誤寫法原因
SELECT DISTINCT title, * FROM book語法錯誤,DISTINCT 不支援 *
SELECT DISTINCT title, author FROM book若 author 不同,仍會回傳多筆
GROUP BY title 直接選其他欄位MySQL ONLY_FULL_GROUP_BY 模式下報錯;非標準 SQL 行為不可攜

掌握子查詢極值 JOIN 或窗口函數,即可精準取得「欄位去重且保留完整列」的結果。

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