跳到主要内容

PostgreSQL SELECT DISTINCT 去重教程

DISTINCT 用于去掉结果中的重复行。本篇覆盖标准 DISTINCT、PostgreSQL 特有的 DISTINCT ON,以及聚合中的 COUNT(DISTINCT …)。

本篇内容​

  • SELECT DISTINCT 单列与多列去重
  • DISTINCT ON (expr):每组保留一行
  • COUNT(DISTINCT …) 统计不重复值
  • 去重与排序的配合

SELECT DISTINCT​

-- 单列去重:所有出现过的状态
SELECT DISTINCT status FROM users;

-- 多列去重:按组合去重,(status, city) 整体不重复即保留
SELECT DISTINCT status, city FROM users;

注意:多列 DISTINCT 是对整行组合去重,不是分别对每列去重。

DISTINCT ON(PostgreSQL 扩展)​

按表达式分组、每组只保留第一行,保留哪行由 ORDER BY 决定:

-- 每个用户只保留最近一笔订单
SELECT DISTINCT ON (user_id) user_id, order_id, amount, created_at
FROM orders
ORDER BY user_id, created_at DESC;

DISTINCT ON 的表达式必须出现在 ORDER BY 的最左侧,否则结果不确定。

待补充(TODO)
  • 补充:DISTINCT 与 GROUP BY 在语义和性能上的差异
  • 补充:COUNT(DISTINCT col) 与 COUNT(DISTINCT (col1, col2)) 的写法
  • 补充:去重查询在大表上的执行代价与替代方案(如先分组再聚合)