SÉLECTIONNEZ CAS vs CAS DANS SQL
Je ne comprends pas très bien pourquoi ces deux codesamples renvoyer une valeur différente.
d'une certaine manière incorrecte, mais de travailler la syntaxe, renvoie des résultats faux, e.g il retourne 0
lorsque la comparaison est faite sur deux valeurs:
(SELECT CASE
WHEN
SUM(V.IsCompatible) OVER
(PARTITION BY ComputerName, UserID) = ApplicationCount
THEN 1 ELSE 0 END
) AS CompatibleUser
Celui-ci renvoie le valeurs correctes, c'est à dire. 1
quand il y a des deux valeurs égales par rapport.
(CASE
WHEN
SUM(V.IsCompatible) OVER
(PARTITION BY ComputerName, UserID) = ApplicationCount
THEN 1 ELSE 0 END
) AS CompatibleUser
ou encore plus simple:
(SELECT CASE
WHEN
X = Y
THEN 1 ELSE 0 END
) AS Result
X = 22 ET Y = 22 => Result = 0
(CASE
WHEN
X = Y
THEN 1 ELSE 0 END
) AS Result
X = 22 ET Y = 22 => Result = 1
Je comprends l'application de la syntaxe correcte est important, et je suis conscient de l'SÉLECTIONNEZ CAS la syntaxe en T-SQL, mais je ne comprends pas comment le premier exemple de code est évalué et la réalisation d'un résultat inattendu.
mise à jour: requête complète dans son contexte
select userapplication.username,
computerdetails.computername,
sum(userapplication.iscompatible)
over (partition by computerdetails.computername,
userapplication.userid) as compatiblecount,
userapplication.applicationcount,
( case
when sum(userapplication.iscompatible)
over (partition by
computerdetails.computername,
userapplication.userid) <> userapplication.applicationcount
then 0
else 1
end
) as usercomputeriscompatible
from computerdetails
right outer join usercomputer
on computerdetails.computerid = usercomputer.computerid
right outer join userapplication
on usercomputer.gebruikerid = userapplication.userid
donc userComputerIsCompatible
est le résultat en question ici
SELECT
clause, le WHERE
clause, HAVING
clause, quelque part d'autre?J'ai ajouté la requête ( un peu modifié dans l'appellation), mais il représente la façon dont il fonctionne
OriginalL'auteur Caspar Kleijne | 2011-11-04
Vous devez vous connecter pour publier un commentaire.
Je pense que la raison de ce comportement est le suivant: les expressions comme
(SELECT ...)
sont considérés comme des sous-requêtes de même qu'ils n'ont pasFROM
clause. Est assumer la source de données pour ces (faux) "sous-requêtes" n'est que le ligne actuelle. Donc,(SELECT expression)
est interprété comme(SELECT expression FROM current_row)
et(SELECT SUM(iscompatible)OVER(...))
est exécuté en tant que(SELECT SUM(iscompatible)OVER(current_row))
.Argument: l'analyse du plan d'exécution pour
(SELECT SUM(IsWeb) OVER(PARTITION BY OrderDate) [FROM current_row])
expressionJe vois un
Constant Scan
(Analyse interne d'une table de constantes) opérateur au lieu deClustered Index Scan
avantSegment
etStream Aggregate
([Expr1007] = Scalar Operator(SUM(@OrderHeader.[IsWeb] as [h].[IsWeb]))
) les opérateurs. Cette table interne (Constant Scan
) est construit à partir de la ligne actuelle.Exemple (testé avec SQL2005SP3 et SQL2008):
Résultats:
SELECT SUM(IsWeb) OVER(PARTITION BY OrderDate)
est clairement juste être appliquées aux colonnes de la ligne actuelle sera donc toujours quelle que soit la valeur deIsWeb
est dans cette ligne.OriginalL'auteur Bogdan Sahlean
J'ai essayé ton code et j'obtiens les mêmes résultats pour les deux requêtes. Voici le code que j'ai essayé:
Résultat est 1 et 1
J'ai couru ce sur SQL Server 2008 R2
À mon avis, le vrai problème n'est pas
CASE ... END
mais commentSUM(V.IsCompatible)
est calculée dans ces deux cas:(SELECT SUM... no_FROM_clause)
et(SUM...)
.OriginalL'auteur Slav