mysql中DISTINCT关键字去重查询的使用方法

1次阅读

DISTINCT作用于整行而非单列,返回唯一组合;ORDER BY字段必须在select列表中;DISTINCT与GROUP BY语义性能不同;NULL在DISTINCT中被视为相同值。

mysql中DISTINCT关键字去重查询的使用方法

DISTINCT 只能作用于 SELECT 后的所有列

DISTINCT 不是独立修饰某一个字段的关键词,它对整个 SELECT 行生效。写成 SELECT DISTINCT name, age FROM user 表示“返回所有唯一的 (name, age) 组合”,而不是“只对 name 去重”。如果想按某个字段去重并取最新/某条记录,DISTINCT 无法直接做到,得用 GROUP BY 或窗口函数。

ORDER BY 必须出现在 DISTINCT 之后且只能引用 SELECT 中的列

mysql 要求 ORDER BY 的字段必须出现在 SELECT DISTINCT 的字段列表中,否则会报错 Error 1055(在 sql_mode=ONLY_FULL_GROUP_BY 下尤其严格)。比如下面语句非法:

SELECT DISTINCT name FROM user ORDER BY created_at;

因为 created_at 没出现在 SELECT 列表里。合法写法是:

SELECT DISTINCT name, created_at FROM user ORDER BY created_at;

或者改用子查询或 GROUP BY 实现排序逻辑。

DISTINCT 和 GROUP BY 在语义和性能上不等价

虽然 SELECT DISTINCT a, b FROM tSELECT a, b FROM t GROUP BY a, b 结果通常一致,但二者底层处理不同:

  • DISTINCT 是去重操作,MySQL 可能用临时表 + 排序或哈希去重
  • GROUP BY 是分组聚合操作,即使没用聚合函数,也会触发分组逻辑,可能更慢、内存占用更高
  • 某些版本 MySQL 对 DISTINCT 有专门优化(如松散索引扫描),而 GROUP BY 可能强制使用临时表

如果只是单纯去重,优先用 DISTINCT;如果后续要加 count()MAX() 等,自然用 GROUP BY

NULL 值在 DISTINCT 中被视为相同值

MySQL 把所有 NULL 当作相等来处理。例如表中有三行:(1, NULL)(2, NULL)(3, NULL),执行:

SELECT DISTINCT col2 FROM t;

结果只返回一个 NULL,不是三个。这点和 UNIQUE 约束行为一致,但容易在统计去重数量时误判——比如 COUNT(DISTINCT col2) 会把全部 NULL 算作 1 次。

如果业务上需要区分“多个 NULL 是否算多次”,就得提前用 IFNULL(col2, UUID()) 或其他标记方式转换,但要注意这会影响索引使用和可读性。

text=ZqhQzanResources