Multiple SQL SELECT WHERE avec INTERSECT, valeur d'espace réservé

J'utilise SQL Server et j'essaie de faire ce qui suit:

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'; 

Cela fonctionne bien. Cependant, j'ai besoin de build un SELECT générique comme:

 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; 

Cependant, à une exécution donnée, je n'aurai probablement pas les cinq valeurs keys. J'ai besoin d'avoir des valeurs de key factices qui ne vont pas interférer avec les INTERSECT.

Par exemple, disons que j'ai seulement 1 valeur, les 4 restants sont nuls. Mais l'INTERSECT ne fonctionne pas (correctement).

Y at-il de toute façon des valeurs factices qui n'interféreront pas avec les INTERSECTS?

Je déteste avoir à faire des ifs nesteds où si je n'ai qu'une seule valeur, je n'effectue qu'un seul SELECT. Si j'ai deux valeurs alors j'ai deux SELECTS avec un INTERSECT intermédiaire et ainsi de suite.

Voici de quoi il s'agit:

Dire que j'ai un mot de 5 caractères, je veux être en mesure de faire un SELECT OERE returnner une list de dire tous les mots de 5 caractères qui ont «je» dans la troisième position. Assez facile. Ensuite, je pourrais vouloir sélectionner où la troisième position est «je» et la cinquième est «e». Cela ressemble à "Roue de la Fortune". Je peux avoir toutes les cinq valeurs de sorte que l'set returnné seulement devrait être respecté. Par conséquent, il serait bien d'avoir un set de 5 SELECTS avec quatre INTERSECTS intermédiaires que cette construction pourrait gérer de 1 à 5 valeurs.

J'ai essayé des valeurs NULL et cela ne fonctionne pas clairement comme il ne devrait pas.

Vous pouvez également build la requête en tant que:

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

Vous devez toujours replace la list IN et le numéro 5. Vous pouvez écrire ceci en utilisant des parameters explicites:

 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); 

Ceci est entièrement paramétrable et gère les valeurs NULL .

MODIFIER:

En fait, vous pouvez le faire avec votre version:

 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; 

L'intersection de toutes les lignes est une intersection non-op.

Gordon cela a fonctionné comme un charme!

 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 

Il me donne les bonnes réponses et le meilleur de tous, je peux maintenant coder la partie c # et avoir une seule requête au lieu d'ifs nesteds …

Johnny