左连接区分不存在和行不匹配的条件?

时间:2016-02-04 15:36:54

标签: sql tsql

使用left join,我试图找到哪个@ Er.id确实存在,或者与@ Si.id不匹配。我知道这可以通过多种方式完成(例如cte),但我有兴趣在left join语句中检查null时使用where

这是我的剧本:

DECLARE @Er table (  ID varchar(20)  )

insert into @Er 
select '001' union 
select '028' union 
select '294' union 
select '352' union 
select '358' union 
select '500'

DECLARE @Si table 
(
    ID varchar(20),
    IsValid varchar(1)
)

insert into @Si 
select '001', 'N' union 
select '028', 'Y' union 
select '294', 'Y' union 
select '352', 'Y' union 
select '358', 'Y' 

select Er.id as 'Er', Si.id as 'Si' from 
@Er er left join @Si si on
Er.id = Si.id
and si.isvalid = 'Y'
where
Si.id is null

通过使用On clause,结果将显示两行:001和500. 001匹配(但不符合on si.isvalid = 'Y')并且@Si上不存在500。问题是我无法区分这两行。

使用Where clause(其中si.isvalid =' Y'),它会自动转换为inner join,因此不会显示任何内容。

通过使用这种语法或类似的语法,有没有办法区分彼此?像这样:

Er    Si     IsValid
001   NULL   N
500   NULL    

感谢。

1 个答案:

答案 0 :(得分:0)

您可以使用两个左连接,但我认为exists更好:

select Er.id as Er, Si.id as Si,
       (case when exists (select 1 from @Si si where si.id = er.id) then 'N'
        end) as IsValid
from @Er er left join
     @Si si
     on Er.id = Si.id and si.isvalid = 'Y'
where Si.id is null;

如果您期望@Si中的一个匹配行,那么我认为以下内容具有所需的逻辑:

select Er.id as Er, NULL as Si, si.IsValid
from @Er er left join
     @Si si
     on Er.id = Si.id and si.isvalid = 'Y'
where Si.id is null or si.isvalid <> 'Y';