如何在LEFT JOIN后去除SQL查询结果中的重复行
解决SQL查询重复行问题
你遇到的重复行是因为一个Person关联多个Address时,LEFT JOIN会生成该Person对应每个Address的行,若Calllist也存在多条关联记录,重复情况会更明显。以下几种方法可实现每个id仅显示一行,任选一个地址信息:
方法1:使用DISTINCT ON(PostgreSQL专属)
PostgreSQL的DISTINCT ON可指定按某字段去重,保留每组的第一行,适配你的场景:
SELECT DISTINCT ON (p.id) p.id, p.first, p.last, p.employer, a.city, a.state, a.county FROM "Person" p LEFT JOIN "Address" a ON p.id = a.person LEFT JOIN "Calllist" cl ON p.id = cl.person ORDER BY p.id; -- 确保每组按id排序,取第一行
方法2:使用聚合函数(通用SQL)
对地址字段使用MAX()或MIN()聚合,配合GROUP BY保留Person的唯一信息:
SELECT p.id, p.first, p.last, p.employer, MAX(a.city) AS city, MAX(a.state) AS state, MAX(a.county) AS county FROM "Person" p LEFT JOIN "Address" a ON p.id = a.person LEFT JOIN "Calllist" cl ON p.id = cl.person GROUP BY p.id, p.first, p.last, p.employer;
MAX()会随机选取一个非空的地址值(存在多个时),换成MIN()效果类似。
方法3:使用窗口函数(通用SQL)
用ROW_NUMBER()给每个Person的行编号,再筛选出编号为1的行:
WITH ranked_persons AS ( SELECT p.id, p.first, p.last, p.employer, a.city, a.state, a.county, ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY (SELECT NULL)) AS rn FROM "Person" p LEFT JOIN "Address" a ON p.id = a.person LEFT JOIN "Calllist" cl ON p.id = cl.person ) SELECT id, first, last, employer, city, state, county FROM ranked_persons WHERE rn = 1;
ORDER BY (SELECT NULL)表示不指定排序规则,数据库会随机选一行;若有偏好,可替换为具体字段(如a.id)。
内容的提问来源于stack exchange,提问作者user2097371
相关产品推荐
相关产品推荐

