繁体   English   中英

SQL JOIN:存在匹配项时,从LEFT和RIGHT表返回行

[英]SQL JOIN: Return rows from LEFT and RIGHT table when there is a match

我有一个#tmp表,我需要从LEFT表和RIGHT表中找到具有匹配的Name和Coverage的所有记录。

-- select * from #tmp
--#tmp table
ID  Name  IsConverted  Coverage  EarliestPolicyEffectiveDate
1   abc   1            Test1     9/1/2017
2   abc   0            Test1     9/2/2017
3   abc   0            Auto      9/3/2017
4   xyz   0            Home      9/3/2017

-- select * from #tmp where IsConverted = 0
--LEFT TABLE
ID  Name  IsConverted  Coverage
2   abc   0            Test1
3   abc   0            Auto
4   xyz   0            Home

-- select * from #tmp where IsConverted = 1
--RIGHT TABLE
ID  Name  IsConverted  Coverage
1   abc   1            Test1

-- DESIRED RESULTS
ID  Name  IsConverted  Coverage
1   abc   1            Test1
2   abc   0            Test1

-- CURRENT RESULTS
ID  Name  IsConverted  Coverage
2   abc   0            Test1



select *
from 
    (SELECT * FROM #tmp tmp WHERE tmp.IsConverted = 0) nc
join
    (SELECT * FROM #tmp tmp WHERE tmp.IsConverted = 1) ic on ic.Name = nc.Name and ic.Coverage = nc.Coverage

我需要能够从左右两个表中获取匹配的记录。 这样做的原因非常复杂,因此不会为此帖子添加任何其他信息。

我尝试了完全外部联接,交叉应用,外部应用。 什么都没用。

编辑:

最好是我想使用JOIN,因为一旦找到匹配的结果,我仍然需要访问左表和右表,因为我需要确保在RIGHT.EarliestPolicyEffectiveDate 15天之内获得LEFT.EarliestPolicyEffectiveDate。

如果我执行UNION ALL,我不确定是否可以这样做。

如下例所示:

select *
from 
    (SELECT * FROM #tmp tmp WHERE tmp.IsConverted = 0) nc
join
    (SELECT * FROM #tmp tmp WHERE tmp.IsConverted = 1) ic on ic.Name = nc.Name and ic.Coverage = nc.Coverage
where 
    nc.EarliestPolicyEffectiveDate between DATEADD(d, -15, ic.EarliestPolicyEffectiveDate) and DATEADD(d, 15, ic.EarliestPolicyEffectiveDate)

我认为有更好的方法可以执行此操作,但是UNION ALLEXISTS似乎在这里起作用:

SELECT *
FROM #tmp t
WHERE IsConverted = 1 
AND EXISTS(SELECT 1 FROM #tmp
           WHERE IsConverted = 0
           AND Name = t.Name
           AND Coverage = t.Coverage)
UNION ALL
SELECT *
FROM #tmp t
WHERE IsConverted = 0
AND EXISTS(SELECT 1 FROM #tmp
           WHERE IsConverted = 1
           AND Name = t.Name
           AND Coverage = t.Coverage);

这对我有用。 有一个子查询来获取LEFT和RIGHT之间的所有匹配名称。 和子查询以获取LEFT和RIGHT之间的所有匹配覆盖率。 然后在WHERE子句中使用“与”将它们链接在一起

select * from #tmp
where name in (Select LEF.Name from LEF 
                INNER JOIN RIG ON LEF.NAME = RIG.NAME) 
        and coverage in (Select LEF.coverage from LEF 
                INNER JOIN RIG ON LEF.coverage = RIG.coverage)

结果:

ID          NAME       IsConverted Coverage   EarliestPolicyEffectiveDate
----------- ---------- ----------- ---------- ---------------------------
1           abc        1           Test1      2017-09-01
2           abc        0           Test1      2017-09-02

我想我现在知道您正在尝试将LEFT TABLE直接连接到RIGHT TABLE,而不是使用#tmp作为中间连接。

您需要将两个相交的位置合并。

伪代码:

SELECT * FROM LEFT TABLE WHERE EXISTS(matching row in RIGHT TABLE)
UNION 
SELECT * FROM RIGHT TABLE WHERE EXISTS(matching row in LEFT TABLE)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM