PostgreSQL中按employee_id去重并获取对应最大id的记录
解决PostgreSQL中获取每个employee_id对应最大id记录的问题
针对你需要获取每个唯一employee_id对应最大id记录的需求,下面提供几种正确的实现方式:
方法一:使用DISTINCT ON(PostgreSQL专属语法)
你之前的DISTINCT ON写法错误在于**ORDER BY必须先包含DISTINCT ON指定的字段**,正确写法如下:
SELECT DISTINCT ON (employee_id) id, employee_id FROM table_name ORDER BY employee_id, id DESC;
逻辑说明:先按employee_id分组,每个分组内按id降序排列,DISTINCT ON会保留每个分组的第一条记录,也就是该employee_id对应id最大的那条数据。
方法二:使用窗口函数ROW_NUMBER()(通用SQL语法,更灵活)
如果需要兼容其他数据库,或者处理更复杂的筛选逻辑,窗口函数是更好的选择:
SELECT id, employee_id FROM ( SELECT id, employee_id, -- 按employee_id分组,组内按id降序给记录标行号 ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY id DESC) AS rn FROM table_name ) AS sub_query WHERE rn = 1;
逻辑说明:通过PARTITION BY employee_id将数据按员工ID拆分分组,每个分组内按id从大到小排序,行号rn=1的就是该分组内id最大的记录。
方法三:分组聚合+表关联
先通过分组聚合找到每个employee_id的最大id,再关联原表获取完整记录:
SELECT t.id, t.employee_id FROM table_name t INNER JOIN ( -- 先找出每个employee_id对应的最大id SELECT employee_id, MAX(id) AS max_id FROM table_name GROUP BY employee_id ) AS agg ON t.employee_id = agg.employee_id AND t.id = agg.max_id;
为什么你的原有查询失败?
- 第一个查询:PostgreSQL的
DISTINCT ON强制要求ORDER BY子句必须以DISTINCT ON指定的字段开头,否则语法逻辑不成立,无法正确分组筛选。 - 第二个查询:子查询中的
ORDER BY在没有LIMIT限制时,PostgreSQL不会保证其排序生效,因此内层的排序不会被DISTINCT ON识别,自然无法得到正确结果。
内容的提问来源于stack exchange,提问作者jokonoo
相关产品推荐
相关产品推荐

