一尘不染

T-SQL-左外部联接-在where子句和on子句中进行过滤

sql

我正在尝试比较两个表以在每个表中找到不在另一个表中的行。表1的groupby列用于在表1中创建2组数据。

groupby     number
----------- -----------
1           1
1           2
2           1
2           2
2           4

表2只有一栏。

number
-----------
1
3
4

因此,表1在组2中具有值1,2,4,表2具有值1,3,4。

加入第2组时,我期望得到以下结果:

`Table 1 LEFT OUTER Join Table 2`
T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
2           2           NULL

`Table 2 LEFT OUTER Join Table 1`
T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
NULL        NULL        3

我可以使它起作用的唯一方法是在第一个联接中放置where子句:

PRINT 'Table 1 LEFT OUTER Join Table 2, with WHERE clause'
select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table1
        LEFT OUTER join table2
        --******************************
        on table1.number = table2.number
        --******************************
WHERE   table1.groupby = 2
    AND table2.number IS NULL

第二个在“打开”中有一个过滤器:

PRINT 'Table 2 LEFT OUTER Join Table 1, with ON clause'
select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table2
        LEFT OUTER join table1
            --******************************
            on table2.number = table1.number
            AND table1.groupby = 2
            --******************************
WHERE   table1.number IS NULL

谁能提出一种不在on子句中而是在where子句中使用过滤器的方法?

上下文是我在数据库中有一个暂存区,我想标识新记录和已删除的记录。groupby字段等效于某个提取物的批次标识,我正在将临时表中的最新提取物与昨天存储在partededs表中的昨天的批次进行比较,该表也具有所有先前提取的批次。创建表1和2的代码:

create table table1 (number int, groupby int)
create table table2 (number int)
insert into table1 (number, groupby) values (1, 1)
insert into table1 (number, groupby) values (2, 1)
insert into table1 (number, groupby) values (1, 2)
insert into table2 (number) values (1)
insert into table1 (number, groupby) values (2, 2)
insert into table2 (number) values (3)  
insert into table1 (number, groupby) values (4, 2)  
insert into table2 (number) values (4)

编辑:

还有更多上下文-
根据我放置过滤器的位置,我会得到不同的结果。如上所述,where子句在一种状态下为我提供正确的结果,而在另一种状态下为我提供正确的结果。我正在寻找一种一致的方式来做到这一点。

在哪里 -

select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table1
        LEFT OUTER join table2
            --******************************
            on table1.number = table2.number
            --******************************
WHERE   table1.groupby = 2 
    AND table2.number IS NULL

结果:

T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
2           2           NULL

在 -

select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table1
        LEFT OUTER join table2
            --******************************
            on table1.number = table2.number
            AND table1.groupby = 2
            --******************************
WHERE   table2.number IS NULL

结果:

T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
1           1           NULL
2           2           NULL
1           2           NULL

哪里(这次表2)-

select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table2
        LEFT OUTER join table1
            --******************************
            on table2.number = table1.number
            AND table1.groupby = 2
            --******************************
WHERE   table1.number IS NULL

结果:

T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
NULL        NULL        3

在 -

select  table1.groupby as [T1_Groupby],
        table1.number as [T1_Number],
        table2.number as [T2_Number]
from    table2
        LEFT OUTER join table1
            --******************************
            on table2.number = table1.number
            --******************************
WHERE   table1.number IS NULL
    AND table1.groupby = 2

结果:

T1_Groupby  T1_Number   T2_Number
----------- ----------- -----------
(0) rows returned

阅读 162

收藏
2021-03-10

共1个答案

一尘不染

如果在WHERE子句中过滤左外部联接表,则实际上是在创建内部联接

另请参见此Wiki页面:左联接的位置条件

2021-03-10