2016-11-09 69 views
0

我有兩個tables右外連接與OR條件和空在where子句 - SQL SERVER

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 

還有查詢的性能沒有太大的改善。所以我試圖用CUL替換Union中的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 clauseUNION一個正確的方法?此外,在WHEREclauseNULL條件從LEFT table消除所有記錄。那麼,在Join期間添加OR子句會有什麼影響?

+1

我不明白您的查詢,第一,是什麼是'AND(table2.val1(...'?它是沒有意義的編譯。第二,你從'data'選擇'val1'是什麼?只有1條記錄從那裏返回?在你的第三個查詢中, 「table1」去哪裏了? – sagi

+0

你的UNION與其他人的查詢不同,它選擇加入data.val的所有記錄1 = table2.val1,加上其他記錄。在你的第一個查詢中,ON條件使用一個AND,而不是OR - 所以它不能和我所見到的一樣 – Cato

+0

@Sagi我錯過了查詢中的IN子句。數據表返回多條記錄......我編輯了這個問題 – bmsqldev

回答

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替換這些)

如果你說錯在您的問題查詢,那麼你應該問問另一個問題與正確的查詢。

+0

恰恰是當我看到查詢時我在想什麼。 –

+0

這實際上是一個報告的現有存儲過程。我知道t2.key = NULL會消除所有的t2錶行。但是,由於Join子句具有OR條件從t2表中獲取數據,所以我很困惑。所以這個和OR條件和這個條款在這裏沒什麼關係? – bmsqldev

+0

@bmsqldev。 。 。 '或'是'JOIN'上的第二個條件。 「關鍵」比較仍然是主要的比較。 –

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