DISTINCT 僅能返回目標列,無法直接獲取其他列。本文通過實例演示為何 DISTINCT col1, col2 不符合預期,並提供 GROUP BY、GROUP_CONCAT、聚合函數等多種實戰解法。
表 test:
| id | test1 | test2 |
|---|---|---|
| 1 | a | 1 |
| 2 | a | 2 |
| 3 | a | 3 |
| 4 | a | 1 |
| 5 | b | 1 |
| 6 | b | 2 |
| 7 | b | 3 |
| 8 | b | 2 |
需求:按 test1 去重,同時返回對應的 id、test2(取每組第一行)。
-- 僅返回目標列
SELECT DISTINCT test1 FROM test; -- 結果: a, b ✓
-- 加入 id 導致去重失效(因 id 唯一)
SELECT DISTINCT test1, id FROM test; -- 返回 8 行 ✗
-- 語法錯誤:DISTINCT 必須置於選項列表首位
SELECT id, DISTINCT test1 FROM test; -- ERROR ✗
SELECT id, test1, test2 FROM test GROUP BY test1;
-- 結果:id=1(test1=a), id=5(test1=b) ✓
-- MySQL 允許 SELECT 非聚合非 GROUP BY 列,取每組第一行(ONLY_FULL_GROUP_BY 關閉時)
SELECT id, GROUP_CONCAT(DISTINCT test1) FROM test GROUP BY test1;
-- 結果:id=1 | a, id=5 | b ✓
-- 缺點:將去重值拼接為字符串,非原始列
SELECT *, COUNT(DISTINCT test1) FROM test GROUP BY test1;
-- 最後一列為常量 1,可忽略 ✓
SELECT t.* FROM test t
INNER JOIN (
SELECT MIN(id) AS min_id FROM test GROUP BY test1
) tm ON t.id = tm.min_id;
-- 明確語義,兼容 ONLY_FULL_GROUP_BY=ON ✓
ONLY_FULL_GROUP_BY,方案一、三會報錯ANY_VALUE() 函數:SELECT ANY_VALUE(id), test1 FROM test GROUP BY test1GROUP BY + ANY_VALUE()(MySQL 5.7+)GROUP_CONCAT 除非確需字符串聚合