当前位置: 首页 > 面试题库 >

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

宓季同
2023-03-14
问题内容

我正在尝试比较两个表以在每个表中找到不在另一个表中的行。表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

问题答案:

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

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



 类似资料:
  • 问题内容: 我在定义为左外部联接的两个表上有一个联接,以便所有记录都从左表返回,即使它们在右表中没有记录也是如此。但是,我还需要在右侧表中的字段上包含where子句,但是....我仍然希望为左侧表中的每个记录返回左侧表中的一行,即使where子句中的条件不满足。有没有办法做到这一点? 问题答案: 是的,将条件(称为谓词)放入联接条件中

  • 我将两个表上的连接定义为左外部连接,以便所有记录都从左表返回,即使它们在右表中没有记录。不过,我还需要包含一个where子句,但是...即使不满足where子句中的条件,我仍然希望为左侧表中的每个记录返回左侧表中的一行。有办法做到这一点吗? 我正在编写带有联接条件的查询,如下所示 以上条件不返回任何行。其中如下条件返回... 输出应为

  • Where 子句用于在从表中获取数据或将其包含在其他表中时生成条件。如果满足条件,则它从表中返回一个特定值。我们使用 WHERE 子句来过滤数据库中的记录并获取主要记录。 在 SELECT 语句中使用了 WHERE 子句,但它也用于 UPDATE、DELETE 帐户等。 语法: 我们使用逻辑运算符生成条件,它们是:、、、、 等。 下面来看一个例子,已更换的理解: 示例 请参阅具有以下记录的 EMP

  • 问题内容: 有什么区别,每个应该有什么区别? 如果我正确理解该理论,则查询优化器应该可以互换使用。 问题答案: 它们不是同一件事。 考虑以下查询: 和 第一个将返回订单及其订单号的行(如果有)。第二个将返回所有订单,但只有订单将具有与之关联的任何行。 使用,子句 实际上是 等效的。但是,仅仅因为它们在功能上相同而产生相同的结果,并不意味着这两种子句具有相同的语义。

  • 问题内容: 在此找到了两个类似的问题,但无法弄清楚如何应用于我的方案。 我的函数有一个名为 @IncludeBelow 的参数。值是0或1(BIT)。 我有这个查询: 如果@IncludeBelow为0,我需要查询如下: 如果@IncludeBelow为1,则最后一行需要排除。(即不应用过滤器)。 我猜想它必须是一条语句,但无法弄清楚语法。 这是我尝试过的: 显然,这是不正确的。 正确的语法是什么

  • 问题内容: 我正在尝试在子句中构建case / if语句。 问题在于该列包含文本和数字。我要与之比较的列是一个整数。 有没有一种方法可以检测列是否包含字符或数字,然后将其设置为0,然后将其设置为0? 这是一个伪查询可以帮助您: 问题答案: 您正在寻找IsNumeric,但它并不总是有效(+,-和。是数字),因此您需要使用GBN所描述的解决方案,即在您的varchar中添加.0e0