You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL查询使用distinct后仍返回重复记录的关联查询改写咨询

问题成因
  • 核心原因是Address表和UserAddress表是1对多的关联关系:1个addressID在Address表中只有1条记录,但在UserAddress表中存在2条对应关联条目。
  • 你使用INNER JOIN时,1行地址数据会匹配到2行用户地址关联数据,最终返回2行内容完全一致的结果。
  • 你移除addressID字段后DISTINCT可以去重,是因为剩余的地址属性完全相同,DISTINCT会合并相同行;而保留addressID时依然返回重复,本质是JOIN产生的重复行未被正确过滤,并非addressID本身不唯一。
重写查询方案

你不需要依赖不稳定的rownum,以下几种写法兼容性强,结果可控:

方案1:使用EXISTS子查询(最推荐,性能最优)

直接判断地址是否存在关联的用户地址记录,不会触发JOIN的行放大效应,天然返回唯一地址:

select a.addressID,a.StreetNumber,a.Street,a.StreetType,a.PostalCode
from Address a
where exists (
    select 1 from UserAddress ca 
    where a.addressID = ca.addressID
)

方案2:先对关联表去重再JOIN

如果你后续需要用到UserAddress的其他字段,可以先对UserAddress按addressID去重,再做1对1关联:

select a.addressID,a.StreetNumber,a.Street,a.StreetType,a.PostalCode
from Address a
inner join (
    -- 先对关联表的addressID去重,避免1对多关联
    select distinct addressID from UserAddress
) ca on a.addressID = ca.addressID

方案3:窗口函数指定取数规则(需要指定关联记录优先级时用)

如果你需要明确取UserAddress中最新/最早的1条关联记录,可以用窗口函数,比rownum结果可控:

select a.addressID,a.StreetNumber,a.Street,a.StreetType,a.PostalCode
from Address a
inner join (
    select 
        addressID,
        -- 按addressID分组,可自定义排序规则,比如按创建时间倒序取最新
        row_number() over(partition by addressID order by create_time desc) as rn
    from UserAddress
) ca on a.addressID = ca.addressID and ca.rn = 1

内容的提问来源于stack exchange,提问作者Notion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:54:04