-3

我有一个类似的查询:

SELECT *
FROM TableA a
LEFT JOIN TABLEB b
ON a.ColA = b.ColA
WHERE b.Col1 IS NULL 
OR (b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate)

我得到一个奇怪的结果集,因为我希望从 TableA 返回每一行,但查询的日期部分搞砸了结果集,只返回 3 行。我知道这一点,因为当我删除日期时间过滤器并保留其他两个过滤器时,我会得到正确的结果。

真的很难过这似乎是“意外行为”,我无法从逻辑上解释为什么会发生这种情况。

4

3 回答 3

3

尽管您的语法错误....

您应该执行右连接,因为 where 子句中的所有逻辑都在表 B 上。

SELECT * 
FROM TABLEB b 
RIGHT JOIN TABLEA a on a.SomeId = b.SomeId
WHERE b.Col1 IS NULL  OR (b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate) 

但是,这可能是您真正想要的...

SELECT *  
FROM TableA a  
LEFT JOIN TABLEB b on b.SomeId = a.SomeId and b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate  
WHERE b.Col1 IS NULL 
于 2012-05-14T15:44:46.310 回答
0

我修复了这个问题,我只是将它们更改为派生表,因此所有谓词都在连接之前应用。

感谢大家的帮助。

于 2012-05-14T17:24:19.557 回答
0

您的 SQL 最好以这种方式编写:

SELECT *
FROM TableA a
LEFT JOIN TABLEB b ON a.col1 = b.col2
WHERE (b.col3 IS NULL) or (b.Col3 BETWEEN @StartDate AND @EndDate)

b.Col1 = A AND b.Col2 = B应该在 LEFT JOIN 部分,因为这是左连接语句的正确语法。

所以上面的 SQL 现在可以翻译成:从 tableA 和 tableB 中选择每一行,其中 tableA 中的 col1 等于 tableB 中的 col2,通过 tableB 中的 col3 过滤结果,它为 null 或通过 tableB 中的 col3 过滤结果,它的值介于@StartDate 和@EndDate。

希望能帮助到你。

此致。

于 2012-05-14T15:48:00.510 回答