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

使用Join关联表后出现重复数据,求正确SQL查询语句

解决LEFT JOIN后重复数据且DISTINCT无效的SQL问题

问题背景

现有两张表Table A和Table B:

  • Table A中StatusID为202的CallID字段为空
  • 通过ContactID字段关联后返回重复数据,使用DISTINCT关键字去重无效
  • 期望得到无重复的指定结果集

表数据

Table A:

StatusIDCallIDContactID
20265490
3021029-213465490

Table B:

DateTimeSessionIDContactID
2023-05-15 02:290341-312465490
2023-05-15 02:301029-213465490

当前问题

仅用ContactID关联后得到4条重复数据(两条目标结果各重复一次),使用DISTINCT未解决问题,已尝试的SQL:

SELECT DISTINCT
  ContactID,
  CallID,
  StatusID,
  DateTime,
  SessionID
from TableA A
JOIN TableB B ON A.ContactID = B.ContactID

期望结果

ContactIDCallIDStatusIDDateTimeSessionID
654902022023-05-15 02:290341-3124
654901029-21343022023-05-15 02:301029-2134

原因分析

仅通过ContactID关联时,Table A的每一行都会与Table B中所有同ContactID的行匹配,生成2*2=4条数据。而你的场景需要更精准的匹配逻辑:

  • Table A中StatusID=302的行,其CallID与Table B的SessionID一致,应匹配对应行
  • Table A中StatusID=202的行,CallID为空,应匹配Table B中SessionID不等于上述CallID的行

解决方案

方案1:优化关联条件

通过精准匹配CallID和SessionID,同时处理空值场景:

SELECT
  A.ContactID,
  A.CallID,
  A.StatusID,
  B.DateTime,
  B.SessionID
FROM TableA A
LEFT JOIN TableB B 
  ON A.ContactID = B.ContactID
  AND (
    A.CallID = B.SessionID
    OR (A.CallID IS NULL AND B.SessionID NOT IN (SELECT CallID FROM TableA WHERE ContactID = A.ContactID AND CallID IS NOT NULL))
  )
WHERE B.DateTime IS NOT NULL; -- 过滤未匹配的空行(按需使用)

方案2:使用窗口函数去重

如果无法确定精准关联条件,可通过窗口函数对重复分组行去重:

SELECT ContactID, CallID, StatusID, DateTime, SessionID
FROM (
  SELECT
    A.ContactID,
    A.CallID,
    A.StatusID,
    B.DateTime,
    B.SessionID,
    ROW_NUMBER() OVER (PARTITION BY A.StatusID, A.CallID ORDER BY B.DateTime) AS rn
  FROM TableA A
  LEFT JOIN TableB B ON A.ContactID = B.ContactID
) t
WHERE rn = 1;

该查询按StatusID和CallID分组,每组仅保留第一行数据,从而得到无重复的结果集。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:53:35