Vous ne pouvez pas utiliser la colonne alias dans les clauses GROUP BY
. S'il vous plaît voir Conceptual Order of Evaluation of a Select Statement, où vous verrez que les clauses sont (logiquement) évaluées dans cet ordre: FROM, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, UNION, ORDER BY
.
Ce n'est pas exactement comment le moteur effectue l'opération, mais c'est une heuristique utile pour une compréhension pratique solide de la raison pour laquelle vous ne pouvez pas utiliser quelque chose de l'instruction SELECT
dans la clause GROUP BY
- il n'est pas logiquement disponible à la clause GROUP BY
car il est évalué plus tard.
Il y a plusieurs façons de contourner cela:
Répétez l'expression entière dans la clause GROUP BY
:
SELECT
City =
CASE location_id when 1 then 'DELHI' when 2 then 'AHMEDABAD'
when 4 then 'HYDERABAD' when 5 then 'KOLKATA' when 6 then 'BANGALORE'
when 7 then 'MUMBAI' when 8 then 'CHENNAI'
END,
Total = Count(*)
FROM #tmptab1
GROUP BY
CASE location_id when 1 then 'DELHI' when 2 then 'AHMEDABAD'
when 4 then 'HYDERABAD' when 5 then 'KOLKATA' when 6 then 'BANGALORE'
when 7 then 'MUMBAI' when 8 then 'CHENNAI'
END
Utilisez une table dérivée:
SELECT
City,
Total = Count(*)
FROM
(
SELECT
City =
CASE location_id when 1 then 'DELHI' when 2 then 'AHMEDABAD'
when 4 then 'HYDERABAD' when 5 then 'KOLKATA' when 6 then 'BANGALORE'
when 7 then 'MUMBAI' when 8 then 'CHENNAI'
END
FROM #tmptab1
) Cities
GROUP BY City;
Utilisez un Expression de table commune (CTE), SQL Server 2005 et plus:
WITH Cities AS (
SELECT
City =
CASE location_id
when 1 then 'DELHI'
when 2 then 'AHMEDABAD'
when 4 then 'HYDERABAD'
when 5 then 'KOLKATA'
when 6 then 'BANGALORE'
when 7 then 'MUMBAI'
when 8 then 'CHENNAI'
END
FROM #tmptab1
)
SELECT
City,
Total = Count(*)
FROM Cities
GROUP BY City;
Utilisez CROSS APPLY, SQL Server 2005 et plus:
SELECT
City,
Total = Count(*)
FROM
#tmptab1
CROSS APPLY (
SELECT
City =
CASE location_id when 1 then 'DELHI' when 2 then 'AHMEDABAD'
when 4 then 'HYDERABAD' when 5 then 'KOLKATA' when 6 then 'BANGALORE'
when 7 then 'MUMBAI' when 8 then 'CHENNAI'
END
) C
GROUP BY City;
Étant donné que votre expression est déterministe, il est possible que vous pouvez simplement faire GROUP BY location_id
, mais ce n'est pas normal Dans ce cas, vous ne devriez pas vous attendre à pouvoir contourner la logique de regroupement d'agrégat normale en sélectionnant une seule colonne, car la plupart du temps une telle expression CASE ajoute une valeur qui n'est pas déterministe. En fait, parce que l'information n'est pas seulement déterministe mais concerne le monde réel (plutôt que les règles métier), je vous recommande de ne pas encoder cette information dans votre requête! Créez une table Location
et rejoignez-la. Il n'est pas recommandé de mettre directement les données utilisateur modifiables dans les requêtes - les requêtes sont censées enregistrer le processus, pas le contenu, et que se passe-t-il si vous ajoutez un nouvel ID de lieu? Toutes les requêtes qui l'utilisent devront changer. De plus, le regroupement par location_id
ne fonctionnera pas correctement si plus d'un location_id
peut faire référence à la même ville.
merci pour l'explication détaillée, vraiment appréciée .. –