PostgreSQL中能否仅当value id和type相同时对user id执行DISTINCT ON?
SQL调整方案
需求可以实现,首先你现有SQL存在两个基础语法错误:
- 关键词拼写错误:
DISTICT应为 PostgreSQL 专用去重语法DISTINCT - 列定义缺少分隔符:
us.id AS id en.type AS type中间缺少逗号,应为us.id AS id, en.type AS type
按需求调整的SQL写法
首先默认你提到的 value id 为 enrollment 表的主键 id,如果是其他字段直接替换下文对应列名即可,根据你实际去重逻辑可以二选一:
场景1:仅对满足 en.id = en.type 的行按user id去重,不满足条件的行全部保留
用UNION ALL拆分两部分逻辑处理:
-- 满足条件的分组取第一条 SELECT DISTINCT ON (us.id) us.id AS id, en.type AS type FROM enrollment AS en INNER JOIN "user" AS us ON us.id = en.user_id WHERE en.id = en.type ORDER BY us.id -- 可追加其他排序字段指定去重时保留的行,比如按enrollment创建时间倒序取最新 UNION ALL -- 不满足条件的行全部保留,不去重 SELECT us.id AS id, en.type AS type FROM enrollment AS en INNER JOIN "user" AS us ON us.id = en.user_id WHERE en.id != en.type
场景2:全局按user id去重,去重时优先保留 en.id = en.type 的行
直接在ORDER BY中加条件排序即可,DISTINCT ON默认取每个分组排序后的第一条:
SELECT DISTINCT ON (us.id) us.id AS id, en.type AS type FROM enrollment AS en INNER JOIN "user" AS us ON us.id = en.user_id ORDER BY us.id, CASE WHEN en.id = en.type THEN 0 ELSE 1 END -- 满足条件的行排在最前优先保留 -- 可追加其他排序字段补充优先级规则
注意事项
- PostgreSQL的
DISTINCT ON必须配合ORDER BY使用,且DISTINCT ON指定的列必须是ORDER BY的前缀列,否则会触发语法报错。 - 如果需要指定去重时保留哪条符合条件的行,可以在对应
ORDER BY后追加排序规则,比如加en.create_time DESC取最新生成的关联数据。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

