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

SQL SELECT查询返回重复记录:如何获取唯一ID及问题解决

重复原因分析
  • 多表连接产生笛卡尔积:members与system_data通过facility_id关联时,若同一facility_id对应多条system_data记录,单条members会被复制为多行。后续与logs连接时,同一个logs.id会绑定到这些重复的members行上,最终即使按logs.id分组,只要其他分组字段(如province/district)存在差异或因连接产生重复行,就会出现logs.id重复的结果。
  • 左连接被转为内连接:where子句中province is not null的条件,过滤掉了system_data无匹配的members记录,使得原本的左连接实际等同于内连接,进一步增加了连接后的重复行数。
  • 分组逻辑冗余:原查询的分组字段包含facility/time/province/district,这些字段与logs.id并非一一对应时,同一个logs.id会被分到多个分组中,导致结果重复;同时count(members.id)因连接产生的重复行,统计结果也不准确。
解决重复问题的方案

根据业务需求,提供两种可行思路:

思路1:先聚合去重,再关联日志表

先对members和system_data的关联结果做去重聚合,再与logs连接,避免笛卡尔积:

select 
    logs.id, 
    to_char(logs.login, 'YYYY-mm-dd') as time,
    m.facility, 
    m.province, 
    m.district, 
    m.member_count as value 
from 
    logs
left join (
    select 
        members.card_id, 
        members.facility_id as facility, 
        max(system_data.province) as province,
        max(system_data.district) as district, 
        count(distinct members.id) as member_count
    from 
        members 
    join 
        system_data on system_data.facility_id = members.facility_id 
    where 
        system_data.province is not null
    group by 
        members.card_id, members.facility_id
) m on logs.card_id = m.card_id and logs.facility_id = m.facility_id
where 
    '2022-08-01' <= logs.login and logs.login <= '2022-08-11'
order by 
    logs.id;

说明:子查询按card_id+facility_id分组,确保每个组合仅返回一条记录;用max()提取同一分组下的province/district(需确保同一facility_id下这些字段值一致),count(distinct)统计真实的成员数量。

思路2:调整分组逻辑,仅按logs.id分组

保留原查询结构,通过聚合函数确保同一logs.id仅返回一条记录:

select 
    logs.id, 
    to_char(max(logs.login), 'YYYY-mm-dd') as time,
    max(members.facility_id) as facility, 
    max(system_data.province) as province, 
    max(system_data.district) as district, 
    count(distinct members.id) as value
from 
    members 
join 
    system_data on system_data.facility_id = members.facility_id 
join 
    logs on logs.card_id = members.card_id and members.facility_id = logs.facility_id  
where
    '2022-08-01' <= logs.login and logs.login <= '2022-08-11' 
    and system_data.province is not null 
group by 
    logs.id
order by 
    logs.id;

说明:将左连接改为内连接(原where条件已过滤无匹配的记录),仅按logs.id分组;对其他字段用max()取唯一值,count(distinct)避免重复统计成员数。

额外注意

  • 明确login字段来源:原查询未指定表名,若members和logs均有该字段会产生歧义,建议改为logs.login或members.login。
  • 若同一facility_id对应不同province/district,需先确认业务逻辑,再调整聚合方式(如筛选特定记录)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:10:52