2017-05-05 17 views
1

我使用SQL服務器,我試圖做到以下幾點:多個SQL SELECT WHERE與相交,佔位符值

SELECT dword FROM Details WHERE dskey = '51a' 
INTERSECT 
SELECT dword FROM Details WHERE dskey = '52b' 
INTERSECT 
SELECT dword FROM Details WHERE dskey = '53i' 
INTERSECT 
SELECT dword FROM Details WHERE dskey = '54d' 
INTERSECT 
SELECT dword FROM Details WHERE dskey = '55e'; 

這工作得很好。不過,我需要建立一個通用的選擇,如:

SELECT dword FROM Details WHERE dskey = value1 
INTERSECT 
SELECT dword FROM Details WHERE dskey = value2 
INTERSECT 
SELECT dword FROM Details WHERE dskey = value3 
INTERSECT 
SELECT dword FROM Details WHERE dskey = value4 
INTERSECT 
SELECT dword FROM Details WHERE dskey = value5; 

然而,在任何給定的執行,我可能不會有所有的5個關鍵值。我需要擁有不會干擾INTERSECT的虛設鍵值。

例如,假設我只有1個值,其餘4個都是空的。但INTERSECT沒有(正確)工作。

是否有虛擬值不會干擾INTERSECTS。

我討厭必須做嵌套的ifs,如果我只有一個值,我只執行一個SELECT。如果我有兩個值,那麼我有兩個選擇與Intertering INTERSECT等。

以下是這是怎麼一回事:

說我有5個字符的話,我希望能夠做一個選擇在何處返回的說不說都5個字符的單詞列表的「I」第三個位置。很簡單。那麼我可能想要選擇第三個位置是'我',第五個是'e'。這就像「幸運之輪」。我可能擁有所有五個值a-b-i-d-e,所以返回的集合只應該遵守。因此,最好有一組5個SELECTS和4個介入INTERSECTS,這個結構可以處理1到5個值。

我試過NULL值,顯然不工作,因爲它不應該。

回答

0

戈登這個工作就像一個魅力!

use wofwords; 
go 

DECLARE @value1 varchar(25) = '51a'; 
DECLARE @value2 varchar(25) = '52b'; 
DECLARE @value3 varchar(25) = NULL; 
DECLARE @value4 varchar(25) = NULL; 
DECLARE @value5 varchar(25) = NULL; 


SELECT dword FROM Details WHERE dskey = @value1 or @value1 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value2 or @value2 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value3 or @value3 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value4 or @value4 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value5 or @value5 IS NULL; 
go 

它給我正確答案和最重要的是,我現在可以編寫了C#的一部分,有一個單獨的查詢,而不是嵌套IFS ...

約翰尼

+1

那麼你應該接受他的回答@Johnny。 – scsimon

1

你也可以構造查詢爲:

SELECT dword 
FROM Details 
WHERE dskey IN (value1, value2, value3, value4, value5) 
GROUP BY dword 
HAVING COUNT(DISTINCT dskey) = 5; 

你仍然需要更換IN列表,你可以寫這個使用明確的參數個數5:

WITH vals as (
     SELECT v.val 
     FROM (VALUES (@value1), (@value2), (@value3), (@value4), (@value5)) v(val) 
    ) 
SELECT dword 
FROM Details d JOIN 
    vals 
    ON d.dskey = vals.val 
GROUP BY dword 
HAVING COUNT(DISTINCT dskey) = (SELECT COUNT(*) FROM vals); 

這是完全可參數化並處理NULL值。

編輯:

其實,你可以用你的版本也這麼做:

SELECT dword FROM Details WHERE dskey = @value1 or @value1 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value2 or @value2 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value3 or @value3 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value4 or @value4 IS NULL 
INTERSECT 
SELECT dword FROM Details WHERE dskey = @value5 or @value5 IS NULL; 

相交的所有行是路口無操作。

+0

戈登和Marc,非常感謝!我會在早上給它螺旋! – Johnny