右外连接OR条件和Null in where子句-SQL SERVER

时间:2016-11-09 11:19:03

标签: sql sql-server tsql join

我有两个tables

table1table2

我的查询如下

select val1, val2 , val3
FROM table1
RIGHT OUTER JOIN
table2 
on ( table1.key = table2.key)
AND (table2.val1 IN (select val1 from data where datadate between @stdate and @enddate) or (table2.val1= 0 and table2.val2 =5))
WHERE table2.key IS NULL

此查询运行速度非常慢

所以我尝试以下面的方式优化它

with cte 
as
(
select key
from table2
where
(table2.val1 IN (select val1 from data where datadate between @stdate and @enddate) or (table2.val1= 0 and table2.val2 =5))
)


select val1, val2 , val3
FROM table1
RIGHT OUTER JOIN
cte
on ( table1.key = cte.key)

WHERE cte.key IS NULL

查询性能仍然没有太大提高。所以我尝试用Ct替换Cte中的OR clause。它改进了查询performance但提供了不同的结果。

with cte 
as
(
select key
from table2
Inner join data
on ( data.val1 = table2.val1)
union
select key
from
table2 where val1 = 0 and val = 5

)

select val1, val2 , val3
FROM table1
RIGHT OUTER JOIN
cte
on ( table1.key = cte.key)

WHERE cte.key IS NULL

OR clause替换UNION是否正确?此外,在WHERE clause中,NULL条件可以消除LEFT table中的所有记录。那么,在OR期间添加Join子句会产生什么影响?

2 个答案:

答案 0 :(得分:2)

我会把原始查询写成:

SELECT val1, val2, val3
FROM table2 t2 LEFT JOIN
     table1 t1
     ON t1.key = t2.key AND
        (t2.val1 IN (select val1 from data where datadate between @stdate AND @enddate) OR
        (t2.val1 = 0 and t2.val2 = 5))
WHERE t2.key IS NULL;

这样写,查询很奇怪。为什么?主要加入条件包括t2.key。如果是NULL,则t1中无法匹配。所以,查询似乎等同于:

SELECT val1, val2, val3
FROM table2 t2 
WHERE ( t2.val1 IN (select val1 from data where datadate between @stdate AND @enddate) OR
        (t2.val1 = 0 and t2.val2 = 5)
      ) AND
      t2.key IS NULL;

(注意:根据SELECT列的来源,您可能需要将其替换为NULL。)

如果您在问题中误解了查询,那么您应该使用正确的查询询问另一个问题。

答案 1 :(得分:1)

我认为你得到的结果会有所不同,因为在你的where条件中缺少日期标准:

select val1 from data where datadate between @stdate and @enddate

尝试下面的sql:

with cte 
as
(
select key
from table2
Inner join data
on ( data.val1 = table2.val1 and datadate between @stdate and @enddate)
union
select key
from
table2 where val1 = 0 and val = 5

)

select val1, val2 , val3
FROM table1
RIGHT OUTER JOIN
cte
on ( table1.key = cte.key)

WHERE cte.key IS NULL