2016-06-16 5 views
1

Il semble que le modificateur d'opérateur de comparaison ALL ne fonctionne pas comme prévu. J'utilise Microsoft SQL Server 2008 R2 Management Studio (v10.50.4000.0).Modificateur SQL Server Opérateur Modifier ALL ne fonctionne pas?

declare @AllTest table 
(
    ID int identity, 
    Crew int, 
    Iteration int, 
    Value varchar(200) 
) 

insert @AllTest 
values 
    (1, 1, 'a'), 
    (2, 1, 'b'), 
    (3, 1, NULL), 
    (1, 2, 'd'), 
    (1, 3, 'e'), 
    (3, 2, NULL), 
    (2, 2, 'a'), 
    (2, 3, 'b'), 
    (1, 4, NULL), 
    (1, 5, 'f') 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration = all(select v from (values (1),(2),(3)) as t(v)) 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration != all(select v from (values (1),(2),(3)) as t(v)) 

La requête où 'Iteration = all' ne renvoie aucun résultat mais il le devrait. La requête où 'Iteration! = All' fonctionne correctement. (Cependant, il semble qu'un tel résultat serait plus facilement réalisé par 'Iteration not in' et sans avoir besoin d'une sorte de sous-requête utilisant quelque chose comme Table Value Constructor ou union pour présenter les valeurs.)

semble vraiment bizarre que ALL ne fonctionne pas comme indiqué et qu'une simple expression telle que 'Iteration = all (1,2,3)' ou 'Iteration! = all (1,2,3)' n'est pas valide!

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration != all(1,2,3) 

Est-ce un problème avec ma version de SQL Server ou que manque-t-il?

Si ALL ne fonctionne pas alors quelle est la meilleure alternative pour construire la requête à se comporter et retourner le résultat qui devrait être produit en utilisant ALL? Je m'excuse de ne pas avoir clarifié ma question en ce qui concerne le résultat escompté. Je cherche un moyen d'avoir seulement un résultat retourné quand il y a des lignes avec la valeur NULL et l'itération égale à 1 et 2 et 3 sans lignes manquantes.

J'espère que cela a du sens.

Aussi, je vois comment 'Iteration = all' cherche une seule ligne, j'ai essayé 'Iteration in all' ce qui aurait plus de sens sémantique mais c'est considéré comme une syntaxe incorrecte.

+0

Vous devez expliquer ce que vous espériez les résultats seraient et pourquoi si vous voulez une alternative, je me fais que vous pourriez vouloir une sorte de requête de division relationnelle. –

Répondre

1
Iteration = all(select v from (values (1),(2),(3)) as t(v)) 

signifie

Iteration = 1 AND Iteration = 2 AND Iteration = 3 

WHERE fonctionne sur une ligne à la fois. Il est impossible que ce qui précède soit vrai pour une seule rangée - donc pas de résultats.


Après avoir modifié une façon d'obtenir votre comportement souhaité est

;WITH CTE 
    AS (SELECT * 
     FROM @AllTest 
     WHERE Crew = 1 
       AND Value IS NOT NULL) 
SELECT * 
FROM CTE 
WHERE NOT EXISTS (SELECT v 
        FROM (VALUES (1), 
            (2), 
            (3)) AS t(v) 
        EXCEPT 
        SELECT c2.Iteration 
        FROM cte c2) 
+0

Merci pour votre aide; J'ai enquêté et décidé que la meilleure solution implique la division relationnelle à laquelle vous avez fait référence.Je n'avais jamais entendu parler de ça auparavant. il semble toujours étrange qu'il n'y ait pas une façon plus simple de construire une requête qui garantira qu'une colonne donnée a des lignes pour toutes les valeurs listées dans l'instruction entre parenthèses; Je comprends que c'est appliquer le terme ALL de la façon que vous avez décrite; puisque '= all (1,2,3)' ne sera jamais vrai tel qu'actuellement interprété, alors le générateur de plan d'exécution devrait le faire d'une manière qui a du sens pour éviter la construction plus compliquée et complexe – Erg

0

Je pense que vous voulez utiliser Tout au lieu de tous. Toutes les oeuvres pour> et <, par exemple:

select 
    * 
from @AllTest 
where 1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration > all(select v from (values (1),(2),(3)) as t(v)) 

Renvoie le record avec f.

ID Crew Iteration Value 
10 1   5   f 

est avec Any:

select 
    * 
from @AllTest 
where 1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration = Any(select v from (values (1),(2),(3)) as t(v)) 

ID Crew Iteration Value 
1 1 1 a 
4 1 2 d 
5 1 3 e 
+0

'= Any' est juste' IN' –

+0

C'est correct, comme indiqué dans cet article. https://technet.microsoft.com/en-us/library/ms187074(v=sql.105).aspx –