2014-10-01 61 views
1

我有一個存儲過程,它需要輸入兩個表類型(每個表只包含一個ID列)。這些過濾器需要應用於存儲過程中的主查詢。我是通過將這兩個表類型參數加入主查詢來完成的。類似下面:有條件地添加/刪除SQL語句中的聯接

SELECT 
    <cols> 
FROM 
    <table> t join @tableVar1 v1 on t.c1 = v1.c1 
      join @tableVar2 v2 on t.c2 = v2.c2 

現在我需要改變這樣的,如果表變量包含任何行,它應該返回回整套程序。所以如果@ tableVar1有0行,我不會加入主查詢。

我想做的事情,我正在努力與具有相同的查詢有條件地不做連接,如果該變量有0行。我可以爲每個組合添加if語句,但這意味着我必須編寫4個查詢。查詢很複雜,恐怕之後所做的更改可能會不同步。

那麼是否有可能在同一個查詢中對性能產生最小影響?感謝你的幫助。

+0

嘗試將INNER JOIN更改爲左外連接: LEFT OUTER JOIN @ tablevar1 v1 ON t.c1 = v1.c1 – Rishabh 2014-10-01 03:48:37

+1

爲什麼不在if-else下使用兩個單獨的查詢?這種方式沒有性能影響,它會更乾淨。 – Jayachandran 2014-10-01 03:50:46

+0

@Jayachandran我目前正在使用不同的查詢,但問題是有兩個變量有4個組合,並且可能會有一個更多的過濾器會使它成爲8個組合,並且它變成了維護地獄。 – v1p3r 2014-10-01 04:03:09

回答

2

像這樣的事情,也許 -

,而不是內部連接,我用左聯接,然後所有的4個條件進入WHERE子句。

declare @countv1 int, @countv2 int 
select @countv1 = COUNT(1) from @tableVar1 
select @countv2 = COUNT(1) from @tableVar2 

SELECT 
    <cols> 
FROM 
    <table> t 
    left join @tableVar1 v1 on t.c1 = v1.c1 
    left join @tableVar2 v2 on t.c2 = v2.c2 
where 
    (@countv1=0 or v1.c1 is not null) 
    and 
    (@countv2=0 or v2.c1 is not null) 
+0

我認爲這應該是訣竅。謝謝! – v1p3r 2014-10-01 05:43:52

0

可以實現有條件使用Dynamic SQL Query

Declare @CntVar1 int 
Declare @CntVar2 int 
Declare @ExSQL nvarchar(max) 

select @CntVar1 = COUNT(1) from @tableVar1 
select @CntVar2 = COUNT(1) from @tableVar2 

Set @ExSQL= 'Select <cols> FROM <table> t' 
IF @CntVar1>=1 
Begin 
    Set @ExSQL = @ExSQL + 'join @tableVar1 v1 on t.c1 = v1.c1' 
End 
    IF @CntVar2>=1 
Begin 
    Set @ExSQL = @ExSQL +'join @tableVar2 v2 on t.c2 = v2.c2' 
End 

Exec Sp_executeSQL @ExSQL 
+1

通常,您希望sql-server將過程的執行計劃保存在緩存中。這加快了下次執行。因此,你會想要避免動態查詢。 – 2014-10-01 05:18:42

+0

在一般情況下,使用動態查詢時,我們不會看到顯着的性能下降。因此,我已經使用了它,並且也在Rahul **問題中詢問了條件加入 – Rajesh 2014-10-01 11:30:23

0

加入另一種可能性可能是這樣的:

declare @t1 TABLE (id int) 
declare @t2 TABLE (id int) 

... 

select * from dbtest1 d where 1 = 
    (case when not exists(select * from @t1) then 1 
     when exists(select * from @t1 t1 where t1.id = d.id) then 1 end) 
AND 1 = 
    (case when not exists(select * from @t2) then 1 
     when exists(select * from @t2 t2 where t2.id = d.id) then 1 end) 

你最好要檢查查詢計劃,並做一些你計時以檢查性能是否令人滿意。