PostgreSQL如何实现手机号去重查询并返回同条记录对应的ID与link
问题原因
你当前使用的写法中,max(ID)和max(link)是两个独立的聚合计算,分别取同一个手机号下所有记录的ID最大值、link最大值,这两个值不一定来自同一条记录,自然会出现ID和link不匹配的问题。
解决方案
方案1:使用PostgreSQL专属DISTINCT ON语法(推荐,性能最优)
这是PostgreSQL特有的简洁语法,专门用来解决分组取首条的场景:
SELECT DISTINCT ON (Phone) ID, Phone, link FROM MyTable -- 先按手机号分组,再按你需要的规则排序,排序后的第一条就是每个手机号要保留的记录 ORDER BY Phone, ID ASC;
如果你的需求是每个手机号保留ID最大的记录,只需要把排序规则改成ORDER BY Phone, ID DESC即可。
方案2:使用窗口函数(兼容标准SQL)
如果需要语法兼容其他数据库,可以用ROW_NUMBER()窗口函数实现:
WITH ranked_records AS ( SELECT ID, Phone, link, -- 按手机号分组,组内按ID排序打行号 ROW_NUMBER() OVER (PARTITION BY Phone ORDER BY ID ASC) AS row_num FROM MyTable ) -- 取每个分组行号为1的记录,所有字段都来自同一条数据 SELECT ID, Phone, link FROM ranked_records WHERE row_num = 1;
说明
两种方案都可以保证返回的ID、Phone、link属于同一条记录,你只需要调整ORDER BY后的排序规则,就可以自定义每个手机号要保留的记录筛选逻辑(比如按创建时间、更新时间排序等)。
内容的提问来源于stack exchange,提问作者David López
相关产品推荐
相关产品推荐

