-- 單欄位去重
SELECT DISTINCT column FROM table;
-- 多欄位去重(組合唯一)
SELECT DISTINCT col1, col2 FROM table;
-- 統計不重複值個數
SELECT COUNT(DISTINCT column) FROM table;
SELECT DISTINCT a, b FROM t 返回的是 (a,b) 元組不重複,而非「a 不重複且保留對應的 b」。
CREATE TABLE student (name VARCHAR(20), age INT);
INSERT INTO student VALUES ('a',5), ('a',5), ('c',0);
SELECT DISTINCT name, age FROM student;
-- 結果:(a,5), (c,0) -- 兩列同時相同才去重
-- 若想「name 不重複,取任意 age」
SELECT name, MAX(age) FROM student GROUP BY name;
-- 結果:(a,5), (c,0)
需求:依某欄位去重,同時返回其他欄位(任意值或聚合值)。
-- 取每個 name 的最新記錄(假設有 id 自增)
SELECT * FROM student
WHERE id IN (SELECT MAX(id) FROM student GROUP BY name);
-- 或使用變數模擬 ROW_NUMBER (MySQL 8.0+ 直接用窗口函數)
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn
FROM student
) t WHERE rn = 1;
-- 統計每首歌被多少歌手演唱,只顯示 >=2 的,按次數降序取前 10
SELECT songname, singerid, COUNT(*) AS cnt
FROM t_song
GROUP BY songname, singerid
HAVING cnt >= 2
ORDER BY cnt DESC, songid ASC
LIMIT 10;
關鍵點:LIMIT 作用於 GROUP BY/HAVING/ORDER BY 之後的結果集,而非原始行。
SELECT COUNT(DISTINCT songid) FROM feedback;
SELECT COUNT(DISTINCT(songid)) FROM feedback; -- 兩者等價
-- MAX/MIN 忽略 NULL,字串按字典序
SELECT MAX(singername) FROM feedback; -- 非空最大值,'zxx' > 'lady'
-- 統計非空值個數
SELECT COUNT(singername) FROM feedback; -- 不計 NULL
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT
因此 SELECT 定義的別名可用於 ORDER BY、GROUP BY、HAVING,但不可用於 WHERE。
-- 原查詢
SELECT feedback_id, songid, MAX(singername), MAX(time) AS new_time
FROM feedback GROUP BY songid ORDER BY new_time DESC;
-- 錯誤改寫
SELECT COUNT(*) FROM feedback GROUP BY songid ORDER BY new_time DESC;
-- 報錯:Unknown column 'new_time' in 'order clause'
-- 原因:SELECT 列表變為 COUNT(*),new_time 別名不存在
DISTINCTDISTINCT col1, col2GROUP BY + 聚合函數 / 窗口函數ROW_NUMBER() (MySQL 8.0+)DISTINCT 作用於整個選取列表,而非單一欄位