的SQL Server:与多个LEFT OUTER JOIN查询和WHERE条件
我运行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
我的第二个问题是:我可以以某种方式改变这种行为吗? (例如,在服务器配置?)
最好的问候, 彼得
第一个问题:没有DB引擎将解释查询相同的,除非你有某种ANSI空值开关混乱的问题在你的2005数据库。它们是不同的,外部连接表中的列上的表达式在ON子句之外是无意义的(无论你理解它还是同意它)。困惑在于你,而不是SQL Server。你所质疑的是如预期的那样。
第二:我希望不是!修复您的查询!
在where语句中添加条件时,只会返回符合这些条件的行,所以在这种情况下使用外连接可能毫无意义。这是由设计,并在SQL2005,2008年相同的方式工作,2012年
关于ANSI NULL:In SQL Server, what does "SET ANSI_NULLS ON" mean?
我完全理解WHERE如何工作 - 我的混淆可能来自于我以某种方式将别名创建连接到ON子句exceution。现在它开始对我显而易见了。谢谢,但花时间回答我的问题! – PiWo
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之前应用条件,从而允许对结果行进行正确的过滤。
谢谢你指出 - 我会检查是否是这种情况(ANSI NULLS)。要清楚:我不会破坏这个逻辑 - 我想理解它。正如我所说的,ANSI NULLS可能会影响MSSQL 2005--那么Oracle服务器呢,我也试过了。 – PiWo
“他们是不同的,外部连接表中的列上的表达式在ON子句之外没有意义”正是我以前的样子。谢谢,这只是解决了我的问题查询。 – Dragick