web-dev-qa-db-fra.com

GROUP BY combiné avec ORDER BY

La clause GROUP BY regroupe les lignes, mais ne trie pas nécessairement les résultats dans un ordre particulier. Pour modifier l'ordre, utilisez la clause ORDER BY, qui suit la clause GROUP BY. Les colonnes utilisées dans la clause ORDER BY doivent figurer dans la liste SELECT, contrairement à l'utilisation normale de ORDER BY. [Oracle par exemple, quatrième édition, page 274]

Pourquoi donc? Pourquoi l'utilisation de GROUP BY influence-t-elle les colonnes requises dans la clause SELECT?

De même, dans le cas où je n'utilise pas GROUP BY: Pourquoi voudrais-je ordonner par certaines colonnes mais ne sélectionner qu'un sous-ensemble de colonnes?

9
fredoverflow

En réalité, la déclaration n'est pas tout à fait vraie, comme le montre l'exemple de Dave Costa. 

La documentation Oracle indique qu'une expression peut être utilisée, mais qu'elle doit être basée sur les colonnes de la liste de sélection.

expr - expr ordonne les lignes en fonction de leur valeur pour expr. L'expression est basée sur des colonnes dans la liste de sélection ou des colonnes dans les tables, les vues ou les vues matérialisées dans le Clause FROM. Source: Oracle® Database Référence du langage SQL 11g version 2 (11.2) E26088-01 Septembre 2011. Page 19-33

Du même ouvrage, pages 19-13 et 19-33 (page 1355 et 1365 dans le PDF)

enter image description here

enter image description here

http://docs.Oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#SQLRF01702

http://docs.Oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2171079

5
hol

Le texte en gras de votre citation est incorrect (il s'agit probablement d'une simplification excessive qui est vraie dans de nombreux cas d'utilisation courants, mais ce n'est pas strictement vrai en tant qu'exigence). Par exemple, cette instruction s'exécute correctement, bien que AVG(val) ne soit pas dans la liste de sélection:

WITH DATA AS (SELECT mod(LEVEL,3) grp, LEVEL val FROM dual CONNECT BY LEVEL < 100)
SELECT grp,MIN(val),MAX(val)
FROM DATA
GROUP BY grp
ORDER BY AVG(val)

Les expressions de la clause ORDER BY doivent simplement pouvoir être évaluées dans le contexte de GROUP BY. Par exemple, ORDER BY val ne fonctionnerait pas dans l'exemple ci-dessus, car l'expression val n'a pas de valeur distincte pour chaque ligne produite par le regroupement.

En ce qui concerne votre deuxième question, vous pouvez vous soucier de la commande, mais pas de la valeur de l'expression de commande. L'exclusion d'expressions inutiles des listes de sélection réduit la quantité de données devant être réellement envoyées du serveur au client.

6
Dave Costa

Premier:

L'implémentation de group by en est une qui crée un nouveau jeu de résultats dont la structure diffère de la clause from d'origine (vue de table ou de certaines tables jointes). Cet ensemble de résultats est défini par ce qui est sélectionné.

Tous les SGBDR SQL n’ont pas cette restriction, bien qu’il soit toujours impératif que ce qui est ordonné soit une fonction d’agrégation des colonnes non groupées (AVG, SUM, etc.) ou l’une des colonnes regroupées par un de ces résultats (par exemple, l'ajout de deux colonnes), car il s'agit d'une exigence logique du résultat de l'opération de regroupement.

Seconde:

Parce que vous ne vous souciez que de cette colonne pour la commande. Par exemple, vous pouvez avoir une liste des célibataires les plus vendus sans donner leurs ventes (les best-sellers du NYT gardent secrets certains détails de leurs données, mais ils ont une liste classée). Bien sûr, vous pouvez contourner ce problème en sélectionnant simplement cette colonne puis en ne l'utilisant pas.

3
Jon Hanna

Exemple de table

sample.grades
Name   Grade    Score
Adam   A        95
Bob    A        97
Charlie C       75

Première requête à l'aide de GROUP BY

Select grade, count(Grade) from sample.grades GROUP BY Grade

Sortie

Grade Count
A     2
C     1

Deuxième requête en utilisant order by

select Name, score from sample grades order by score

Sortie

Bob    A        97
Adam   A        95
Charlie C       75

Troisième requête à l'aide de GROUP BY et de la commande

Select grade, count(Grade) from sample.grades GROUP BY Grade desc

Sortie

Grade Count
A     2
C     1

Une fois que vous commencez à utiliser des choses comme Count, vous devez avoir un groupe. Vous pouvez les utiliser ensemble, mais ils ont des utilisations très différentes, comme j'espère que les exemples le montrent clairement.

Pour essayer de répondre à la question, pourquoi grouper par affecte les éléments de la section select, parce que c'est ce que group by est censé faire. Vous ne pouvez pas faire le compte d'une colonne si vous ne groupez pas par cette colonne.

Deuxième question, pourquoi voudriez-vous commander par mais pas sélectionner toutes les colonnes?

select name from sample.grades order by score

Sortie

Name
Bob
Adam
Charlie
2

Les données sont agrégées avant d'être triées pour ORDER BY.

Si vous essayez de classer par une autre colonne (qui ne fait pas partie de la liste de regroupement ou d'une fonction d'agrégation), quelle valeur serait utilisée? Il n'y a pas de valeur unique à utiliser pour la commande.

Je crois que vous pouvez utiliser des combinaisons de valeurs pour le tri. Alors vous pouvez dire:

order by a+b

Si a et b sont dans le groupe par. Vous ne pouvez simplement pas introduire de colonnes non mentionnées dans le SELECT. Je crois que vous pouvez utiliser des fonctions d'agrégation non mentionnées dans le SELECT, cependant.

2
Gordon Linoff

Quels résultats souhaitez-vous voir classer par colonnes non répertoriées dans la liste de sélection et ne participant pas à la clause group by? Dans tous les cas, tous les types de tri non mentionnés dans les colonnes de la liste SELECT seront omis. Les utilisateurs Oracle ont donc ajouté la restriction correctement.

with c as (
select 1 id, 2 value from dual
union all
select 1 id, 3 value from dual
union all
select 2 id, 3 value from dual
)
select id
from c
group by id
order by count(*) desc
0
Alexander Tokarev

Voici mon entendement

"La clause GROUP BY regroupe les lignes, mais elle ne trie pas nécessairement les résultats dans un ordre particulier."

-> vous pouvez utiliser Group by sans commande par

"Pour modifier l'ordre, utilisez la clause ORDER BY, qui suit la clause GROUP BY."

-> les lignes sont sélectionnées par défaut avec la clé primaire, et si vous ajoutez un ordre, vous devez ajouter après le groupe par

"Les colonnes utilisées dans la clause ORDER BY doivent apparaître dans la liste SELECT, contrairement à l'utilisation normale de ORDER BY."

0
Aghilas Yakoub