354 votes

La raison de la colonne est invalide dans la liste de sélection car elle n'est pas contenue dans une fonction d'agrégat ou dans la clause GROUP BY

J'ai une erreur -

La colonne 'Employee.EmpID' est invalide dans la liste de sélection car elle n'est pas contenue dans une fonction d'agrégation ou dans la clause GROUP BY.


select loc.LocationID, emp.EmpID
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by loc.LocationID 

Cette situation correspond à la réponse donnée par Bill Karwin.

correction pour la requête ci-dessus, correspond à la réponse par ExactaBox -

select loc.LocationID, count(emp.EmpID) -- ne pas utiliser count(*), je ne veux pas compter les valeurs nulls
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by loc.LocationID 

QUESTION ORIGINALE -

Pour la requête SQL -

select *
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by (loc.LocationID)

Je ne comprends pas pourquoi j'ai cette erreur. Tout ce que je veux faire est de joindre les tables et ensuite regrouper tous les employés dans un emplacement particulier ensemble.

Je pense avoir une explication partielle pour ma propre question. Dites-moi si c'est correct -

Pour grouper tous les employés qui travaillent dans le même emplacement, nous devons d'abord mentionner l'ID de l'emplacement.

Ensuite, nous ne pouvons pas/ne mentionnons pas chaque ID d'employé à côté. Au lieu de cela, nous mentionnons le nombre total d'employés dans cet emplacement, c'est-à-dire que nous devrions utiliser SUM() des employés travaillant dans cet emplacement. Pourquoi le faisons-nous de cette manière-là, je ne suis pas sûr. Cela explique donc la partie "elle n'est pas contenue dans une fonction d'agrégation" de l'erreur.

Quelle est l'explication pour la partie de l'erreur concernant la clause GROUP BY ?

1 votes

Lorsque vous utilisez group by, vous devez sélectionner spécifiquement l'élément que vous regroupez

2 votes

Vous confondez probablement GROUP BY avec ORDER BY. Le regroupement est utilisé pour regrouper des colonnes; l'ordonnancement trie le résultat.

689voto

Bill Karwin Points 204877

Supposons que j'ai la table suivante T:

a   b
--------
1   abc
1   def
1   ghi
2   jkl
2   mno
2   pqr

Et je fais la requête suivante:

SELECT a, b
FROM T
GROUP BY a

La sortie devrait avoir deux lignes, une ligne où a=1 et une seconde ligne où a=2.

Mais quelle devrait être la valeur de b affichée sur chacune de ces deux lignes? Il y a trois possibilités dans chaque cas, et rien dans la requête ne précise quelle valeur choisir pour b dans chaque groupe. C'est ambigu.

Cela démontre la règle de la valeur unique, qui interdit les résultats indéfinis que vous obtenez lorsque vous exécutez une requête GROUP BY, et que vous incluez des colonnes dans la liste de sélection qui ne font partie ni des critères de regroupement, ni n'apparaissent dans des fonctions d'agrégat (SUM, MIN, MAX, etc.).

Le corriger pourrait ressembler à ceci:

SELECT a, MAX(b) AS x
FROM T
GROUP BY a

Maintenant, il est clair que vous voulez le résultat suivant:

a   x
--------
1   ghi
2   pqr

4 votes

Bill - un aside - vous avez dit qu'il n'est pas "clair quel valeur choisir pour b dans chaque groupe". Pourquoi est-ce que SQL ne met pas b1, b2, b3 tous ensemble dans cette colonne ?

24 votes

@davidblaine, MySQL a une fonction GROUP_CONCAT() pour cela. dev.mysql.com/doc/refman/5.5/fr/… Mais en SQL standard, chaque colonne ne doit contenir qu'une seule valeur. C'est également fondamental pour la théorie relationnelle.

55 votes

J'adore quand les gens prennent le temps d'expliquer en utilisant les premiers principes. Excellente explication, Bill. Merci.

95voto

John Woo Points 132738

Votre requête fonctionnera dans MYSQL si vous définissez le mode serveur ONLY_FULL_GROUP_BY sur désactivé (et c'est le cas par défaut). Mais dans ce cas, vous utilisez un SGBD différent. Pour que votre requête fonctionne, ajoutez toutes les colonnes non agrégées à votre clause GROUP BY, par exemple

SELECT col1, col2, SUM(col3) totalSUM
FROM tableName
GROUP BY col1, col2

Les colonnes non agrégées signifient que la colonne n'est pas utilisée dans des fonctions agrégées comme SUM, MAX, COUNT, etc..

1 votes

Cela fonctionne à merveille avec de multiples jointures internes.

0 votes

Comment puis-je écrire avec ef core

19voto

ExactaBox Points 1988

"Tout ce que je veux faire, c'est joindre les tables puis regrouper tous les employés dans un lieu particulier ensemble."

Il semble que ce que vous voulez est que la sortie de l'instruction SQL liste chaque employé de l'entreprise, mais d'abord toutes les personnes dans le bureau d'Anaheim, puis les personnes dans le bureau de Buffalo, puis les personnes dans le bureau de Cleveland (A, B, C, compris, évidemment je ne sais pas quels sont les lieux que vous avez).

Dans ce cas, supprimez l'instruction GROUP BY. Tout ce dont vous avez besoin est ORDER BY loc.LocationID

3 votes

Ce n'est pas ce que je voulais. Trier par mettra tous les employés dans la même ville les uns après les autres. Il fera cela pour toutes les villes. J'avais besoin de savoir combien d'employés dans une ville au lieu de quels employés dans une ville. Cela a du sens ?

7 votes

Ensuite, remplacez la première ligne de votre exemple original par : SELECT loc.LocationID, COUNT(*)

3 votes

Oui, c'est ce que je voulais. Merci. On dirait que je n'ai pas correctement formulé ma question. Mais, la réponse de Bill Karwin m'a fait comprendre la raison derrière l'erreur. Donc, j'ai accepté la sienne. Merci encore.

18voto

Alex W Points 11502

Fondamentalement, ce que signifie cette erreur est que si vous utilisez la clause GROUP BY, alors votre résultat sera une relation/table avec une ligne pour chaque groupe, donc dans votre instruction SELECT vous ne pouvez "sélectionner" que la colonne par laquelle vous groupez et utiliser des fonctions d'agrégation sur cette colonne car les autres colonnes n'apparaîtront pas dans la table résultante.

1 votes

Bon résumé. J'ai posté une réponse complémentaire ici - stackoverflow.com/a/63545571/2806819

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X