2013-11-22 137 views
1

我运行SQL Server 2008和我试图执行下面的SQL查询:的SQL Server:与多个LEFT OUTER JOIN查询和WHERE条件

查询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声明之后的条件确实搞砸了LEFT OUTER JOIN,并且通常使其表现得像经典INNER JOIN。有趣的,它不是SQL Server上的情况下,2005年

要解决它,我可以这样做:

查询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

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

最好的问候, 彼得

回答

2

第一个问题:没有DB引擎将解释查询相同的,除非你有某种ANSI空值开关混乱的问题在你的2005数据库。它们是不同的,外部连接表中的列上的表达式在ON子句之外是无意义的(无论你理解它还是同意它)。困惑在于你,而不是SQL Server。你所质疑的是如预期的那样。

第二:我希望不是!修复您的查询!

+0

谢谢你指出 - 我会检查是否是这种情况(ANSI NULLS)。要清楚:我不会破坏这个逻辑 - 我想理解它。正如我所说的,ANSI NULLS可能会影响MSSQL 2005--那么Oracle服务器呢,我也试过了。 – PiWo

+0

“他们是不同的,外部连接表中的列上的表达式在ON子句之外没有意义”正是我以前的样子。谢谢,这只是解决了我的问题查询。 – Dragick

1

在where语句中添加条件时,只会返回符合这些条件的行,所以在这种情况下使用外连接可能毫无意义。这是由设计,并在SQL2005,2008年相同的方式工作,2012年

关于ANSI NULL:In SQL Server, what does "SET ANSI_NULLS ON" mean?

+0

我完全理解WHERE如何工作 - 我的混淆可能来自于我以某种方式将别名创建连接到ON子句exceution。现在它开始对我显而易见了。谢谢,但花时间回答我的问题! – PiWo

1
SELECT * 
FROM tableA 
LEFT OUTER JOIN (SELECT * FROM tableB WHERE some_attribute = 'X') AS tabX ON tabX.some_id = tableA.some_id 
AND 
LEFT OUTER JOIN (SELECT * FROM tableB WHERE some_attribute = 'Y') AS tabY ON tabY.some_id = tableA.some_id 

尝试采取开出的条件WHERE子句,并将其纳入到JOIN表。这种方式在OUTER JOINs之前应用条件,从而允许对结果行进行正确的过滤。