LEFT JOIN在多列上有不需要的重复

时间:2015-06-21 15:05:05

标签: sql sql-server-2005 duplicates left-join

我一直在圈子里运行一个让我疯狂的查询。

背景:
我有两张桌子,不幸的是,两张桌子都有重复的记录。 (如果将其置于透视图中,则处理活动日志)。每个表来自不同的系统,我试图将数据加入到一起以获得完整的sudo图片(我意识到我不会得到完美的视图,因为两个系统之间没有共享“事件密钥”;我是尝试匹配元数据的合成。)

以下是我的工作内容:

Table1 
------------
JobID      CustID      Name      ActionDate             IsDuplicate
12345      11111       Ryan      1/1/2015 01:20:20      False
12345      11112       Bob       1/1/2015 02:10:20      False
12345      11111       Ryan      1/1/2015 04:15:35      True
12346      11113       Jim       1/1/2015 05:10:40      False
12346      11114       Jeb       1/1/2015 06:10:40      False
12346      11111       Ryan      1/1/2015 07:10:30      False

Table2 
------------
ResponseID   CustID     ActionDate            Browser
11123        10110      12/1/2014 23:32:15    IE
12345        11111      1/1/2015 03:20:20     IE
12345        11112      1/1/2015 05:10:20     Firefox
12345        11111      1/1/2015 06:15:35     Firefox
12346        11113      1/1/2015 07:10:40     Chrome
12346        11114      1/1/2015 08:10:40     Chrome
12346        11111      1/1/2015 10:10:30     Safari
12213        11123      2/1/2015 01:10:30     Chrome

请注意以下几点:
- JobID和ResponseID是一回事 - JobID和ResponseID是网站上事件的指标(人们正在响应事件)
- 行动日期不匹配(系统2有一个不一致的2小时延迟,但从未超过3小时延迟)
- 注意表2没有重复的标志
- 表1(~2,000条记录)明显小于表2(~16,000条记录)
- 注意Cust 11111在浏览器上浏览,在不同的时间在作业12345上执行相同的操作两次,并且仅在作业12346上执行一次操作

我在寻找:

Result (ideal)
------------
t1.JobID   t1.CustID  t1.Name  t1.ActionDate      t2.Browser
12345      11111      Ryan     1/1/2015 01:20:20  IE
12345      11112      Bob      1/1/2015 02:10:20  Firefox
12345      11111      Ryan     1/1/2015 04:15:35  Firefox
12346      11113      Jim      1/1/2015 05:10:40  Chrome
12346      11114      Jeb      1/1/2015 06:10:40  Chrome
12346      11111      Ryan     1/1/2015 07:10:30  Safari

请注意,我只想要对Table1中的记录进行匹配。由于加入,我得到了大量的重复......这令人沮丧。

这是我到目前为止(我可以谦卑地说,不是非常接近):

SELECT
  t1.JobID,
  t1.CustID,
  t1.Name,
  t1.ActionDate,
  t2.Browser
FROM
  Table1 t1
LEFT OUTER JOIN
  Table2 t2
 ON
  t1.JobID=t2.ResponseID AND 
  t1.CustID=t2.CustID AND
  DATEPART(dd,t1.ActionDate)=DATEPART(dd,t2.ActionDate)

2 个答案:

答案 0 :(得分:0)

尝试更改日期的连接条件,以检查t2.actiondate是否满足条件t1.actiondate <= t2.actiondate <= t1.actiondate + 3 hours

SELECT 
    t1.JobID, t1.CustID, t1.Name, t1.ActionDate, t2.Browser
FROM
    Table1 t1 
LEFT JOIN Table2 t2
       ON t1.JobID = t2.ResponseID
      AND t1.CustID = t2.CustID
      AND t2.ActionDate >= t1.ActionDate
      AND t2.ActionDate <= DATEADD(hour, 3, t1.ActionDate)
ORDER BY t1.JobID , t1.ActionDate;

使用您的示例数据,此查询的结果与您想要的结果相符。

答案 1 :(得分:0)

一种方法是使用row_number()枚举每个表,并匹配序列号:

select t1.JobID, t1.CustID, t1.Name, t1.ActionDate, t2.Browser
from (select t1.*,
             row_number() over (partition by JobId, CustId order by ActionDate) as seqnum
      from table t1
     ) t1 join
     (select t2.*
             row_number() over (partition by ResponseId, CustId order by ActionDate) as seqnum
      from table t2
     ) t2
     on t1.JobId = t2.ResponseId and
        t1.CustId = t2.CustId and
        t1.seqnum = t2.seqnum;

这适用于您的样本数据。但是,如果每个作业都没有响应,则对齐可能会失控。如果这是可能的,那么日期算术可能是更好的解决方案。