Sql server SQL Server:具有多个左外部联接和WHERE条件的查询

Sql server SQL Server:具有多个左外部联接和WHERE条件的查询,sql-server,sql-server-2008,left-join,where,Sql Server,Sql Server 2008,Left Join,Where,我运行SQL Server 2008并尝试执行以下SQL查询: 查询1: SELECT * FROM tableA LEFT OUTER JOIN tableB AS tabX ON tabX.some_id = tableA.some_id LEFT OUTER JOIN tableB AS tabY ON tabY.some_id = tableA.some_id WHERE tabX.some_attribute = 'X' AND tabY.some_attribute = 'Y' 我

我运行SQL Server 2008并尝试执行以下SQL查询:

查询1:

SELECT *
FROM tableA
LEFT OUTER JOIN tableB AS tabX ON tabX.some_id = tableA.some_id
LEFT OUTER JOIN tableB AS tabY ON tabY.some_id = tableA.some_id
WHERE tabX.some_attribute = 'X'
AND tabY.some_attribute = 'Y'
我已经知道,
WHERE
语句之后的条件确实会弄乱
左外部联接
,通常使其行为类似于经典的
内部联接
。有趣的是,SQLServer2005上的情况并非如此

要解决此问题,我可以执行以下操作:

查询2:

SELECT *
FROM tableA
LEFT OUTER JOIN tableB AS tabX ON tabX.some_id = tableA.some_id AND tabX.some_attribute = 'X'
LEFT OUTER JOIN tableB AS tabY ON tabY.some_id = tableA.some_id AND tabY.some_attribute = 'Y'
基本上,我必须在
ON
语句中包含
WHERE
条件,并且查询将按预期方式执行

我的第一个问题是:为什么SQL Server不能以相同的方式解释这两个查询(就像旧的SQL Server版本或Oracle DBServer那样)

我问这个问题是因为我对第一个查询的条件(在
WHERE
语句之后)如何以及为什么会影响主要的逻辑储备(我指的是“主要结果”)感到困惑。特别是因为这两种情况都特别涉及别名tabX和tabY

我的第二个问题是:我能改变这种行为吗?(例如,在服务器配置中?)

致以最良好的祝愿,
Piotr

第一个问题:没有数据库引擎会对查询进行相同的解释,除非您在2005数据库中使用了某种ANSI NULL开关来混淆问题。它们是不同的,外部联接表中列上的表达式在on子句之外毫无意义(无论您是否理解它)。困惑在于您,而不是SQL Server。你所质疑的是意料之中的


第二:我希望不是!修正你的疑问

第一个问题:没有数据库引擎会对查询进行相同的解释,除非您在2005数据库中使用了某种ANSI NULLS开关来混淆问题。它们是不同的,外部联接表中列上的表达式在on子句之外毫无意义(无论您是否理解它)。困惑在于您,而不是SQL Server。你所质疑的是意料之中的


第二:我希望不是!修正你的疑问

在where语句中放置条件时,只返回与这些条件匹配的行,因此在这种情况下使用外部联接可能毫无意义。这是设计的,在SQL2005、2008、2012中也是如此


关于ANSI NULL:

在where语句中放置条件时,只返回与这些条件匹配的行,因此在这种情况下使用外部联接可能毫无意义。这是设计的,在SQL2005、2008、2012中也是如此

关于ANSI NULL:

尝试将条件从WHERE子句中取出,并将其包含到联接表中。这样,在外部联接之前应用条件,允许对结果行进行正确的筛选


尝试将条件从WHERE子句中取出,并将其包含到联接表中。这样,在外部联接之前应用条件,允许对结果行进行正确筛选。

左外部联接-ON子句与WHERE子句

对于左外部联接,对于相同的条件,根据其放置的位置(join子句或where子句),存在很大的差异

使用MS SQL Server:

DECLARE @t1 TABLE ( id INT )
INSERT INTO @t1 VALUES ( 1 ),( 2 ),( 3 ),( 4 ),( 5 );

DECLARE @t2 TABLE ( id INT )
INSERT INTO @t2 VALUES ( 2 ),( 3 ),( 10 ),( 11 ),( 12 );

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2
正如预期的那样,驱动表中的所有行都为空,表示与从属表中的不匹配

ON子句中的条件

对于ON条款中的条件:

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id AND t1.id = 2
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2
在这里,驱动表的列被保留,但join子句将使从属表中不匹配的行为空

WHERE子句中的条件

对于WHERE条款中的条件:

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id
WHERE t1.id = 2
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2

这仅给出匹配的行,因为where子句逐行筛选出与join子句之后应用的条件不匹配的所有行。

左侧外部join-on子句与where子句

对于左外部联接,对于相同的条件,根据其放置的位置(join子句或where子句),存在很大的差异

使用MS SQL Server:

DECLARE @t1 TABLE ( id INT )
INSERT INTO @t1 VALUES ( 1 ),( 2 ),( 3 ),( 4 ),( 5 );

DECLARE @t2 TABLE ( id INT )
INSERT INTO @t2 VALUES ( 2 ),( 3 ),( 10 ),( 11 ),( 12 );

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2
正如预期的那样,驱动表中的所有行都为空,表示与从属表中的不匹配

ON子句中的条件

对于ON条款中的条件:

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id AND t1.id = 2
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2
在这里,驱动表的列被保留,但join子句将使从属表中不匹配的行为空

WHERE子句中的条件

对于WHERE条款中的条件:

SELECT * FROM @t1 t1
LEFT OUTER JOIN @t2 t2 ON t2.id = t1.id
WHERE t1.id = 2
这使得:

1   NULL
2   2
3   3
4   NULL
5   NULL
1   NULL
2   2
3   NULL
4   NULL
5   NULL
2   2

这只会给出匹配的行,因为where子句会逐行筛选出与join子句之后应用的条件不匹配的所有行。

感谢您指出这一点-我将检查是否是这种情况(ANSI NULLS)。要明确的是:我并没有破坏这一逻辑——我想理解它。正如我所说的,ANSI NULLS可能会影响MSSQL 2005——那么Oracle Server呢,我也试过了。“它们是不同的,外部联接表中列上的表达式在on子句之外毫无意义”,这正是我想要的。谢谢,这刚刚修复了我的问题查询。谢谢你指出这一点-我将检查是否是这种情况(ANSI NULLS)。要明确的是:我并没有破坏这一逻辑——我想理解它。正如我所说的,ANSI NULLS可能会影响MSSQL 2005——那么Oracle Server呢,我也试过了。“它们是不同的,外部联接表中列上的表达式在on子句之外毫无意义”,这正是我想要的。谢谢,这刚刚解决了我的问题。我完全理解WHERE是如何工作的——我的困惑可能是因为我以某种方式将别名的创建与ON子句的执行联系起来了。现在我开始明白了。谢谢你花时间回答我的问题!!我完全理解何处工作——我的困惑可能来自于