453 votes

Y a-t-il une différence entre GROUP BY et DISTINCT ?

J'ai appris quelque chose de simple sur SQL l'autre jour :

SELECT c FROM myTbl GROUP BY C

A le même résultat que :

SELECT DISTINCT C FROM myTble

Ce qui m'intrigue, c'est de savoir s'il y a quelque chose de différent dans la façon dont un moteur SQL traite la commande, ou si c'est vraiment la même chose ?

Je préfère personnellement la syntaxe distincte, mais je suis sûr que c'est plus par habitude qu'autre chose.

EDIT : Il ne s'agit pas d'une question sur les agrégats. L'utilisation de GROUP BY avec des fonctions agrégées est comprise.

20 votes

Il ne s'agit pas d'une question sur les agrégats, mais d'un GROUP BY fonctionnant de la même manière qu'un distinct lorsqu'aucune fonction d'agrégat n'est présente.

2 votes

Vous pouvez également faire SELECT c FROM myTbl UNION SELECT c FROM myTbl et obtenir le même résultat... Mais pourquoi compliquer les choses quand SELECT DISTINCT est si facile.

0 votes

L'"ordre logique d'exécution" de GROUP BY est bien antérieure à "SELECT" et DISTINCT suit la sélection.

321voto

Skeolan Points 1116

MusiGenesis Le serveur SQL est suffisamment intelligent pour comprendre que si vous utilisez "Group By" sans utiliser de fonctions d'agrégation, ce que vous voulez dire en réalité est "Distinct" - et il génère donc un plan d'exécution comme si vous aviez simplement utilisé "Distinct".

Cependant, je pense qu'il est important de noter Hank Le traitement cavalier de "Group By" et "Distinct" peut conduire à des problèmes pernicieux si vous ne faites pas attention. Il n'est pas tout à fait correct de dire qu'il ne s'agit "pas d'une question sur les agrégats", car votre question porte sur la différence fonctionnelle entre deux mots-clés de requête SQL, dont l'un est destiné à être utilisé avec des agrégats et dont l'un ne l'est pas.

Un marteau peut parfois servir à enfoncer une vis, mais si vous avez un tournevis à portée de main, à quoi bon ?

0 votes

Je suis tout à fait d'accord avec vous Skeolan. J'ai été assez surpris lorsque j'ai découvert cette fonctionnalité. Ce n'est pas quelque chose que je prévois d'utiliser, mais c'est une façon de faire les choses dans le nouvel endroit où je travaille.

0 votes

Au moins dans Oracle 12, il semble y avoir des cas où DISTINCT, l'obtention de valeurs distinctes par UNION, et GROUP BY fonctionnent différemment. J'ai eu un cas plus tôt dans la journée où DISTINCT et distinct par UNION ont provoqué une erreur d'Oracle, mais GROUP BY a fonctionné ; je ne sélectionnais qu'une colonne dans une vue et je n'utilisais pas d'agrégation ; je ne comprends toujours pas pourquoi cela était nécessaire, mais cela confirme qu'il existe une différence dans l'exécution. Comme d'autres l'ont souligné, il vous permet également de GROUPER PAR les colonnes qui ne sont pas dans la sélection, bien que cela soit rarement nécessaire sans agrégation.

1 votes

Lorsqu'il s'agit de SQL, vous disposez toujours d'un tournevis et d'un marteau. Pourquoi utiliser un marteau pour enfoncer une vis ?

183voto

Glomek Points 12183

GROUP BY vous permet d'utiliser des fonctions d'agrégation, comme AVG , MAX , MIN , SUM y COUNT . Autre main DISTINCT supprime simplement les doublons.

Par exemple, si vous avez un tas d'enregistrements d'achats, et que vous voulez savoir combien a été dépensé par chaque département, vous pouvez faire quelque chose comme ça :

SELECT department, SUM(amount) FROM purchases GROUP BY department

Vous obtiendrez ainsi une ligne par département, contenant le nom du département et la somme de tous les éléments suivants amount dans toutes les lignes de ce département.

5 votes

Je comprends l'utilisation de GROUP BY. Ma question porte sur le fait qu'il renvoie un ensemble de données distinct lorsqu'aucune fonction d'agrégation n'est présente.

3 votes

Parce que GROUP BY effectue implicitement un DISTINCT sur les valeurs de la colonne par laquelle vous regroupez (désolé pour la cacophonie).

0 votes

N'est-il pas possible d'utiliser DISTINCT + un agrégat de fonctions ? comme ceci : select distinct department, SUM(amount) from ...

52voto

MusiGenesis Points 49273

Il n'y a pas de différence (dans SQL Server, au moins). Les deux requêtes utilisent le même plan d'exécution.

http://sqlmag.com/database-performance-tuning/distinct-vs-group

Peut-être qu'il y a est une différence, si des sous-requêtes sont impliquées :

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

Il n'y a aucune différence (style Oracle) :

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:32961403234212

39voto

jkramer Points 7271

Utilice DISTINCT si vous voulez juste supprimer les doublons. Utilisez GROUPY BY si vous voulez appliquer des opérateurs d'agrégation ( MAX , SUM , GROUP_CONCAT , ..., ou un HAVING clause).

22voto

Dave Costa Points 25282

Je suppose qu'il est possible qu'il y ait des différences subtiles dans leur exécution. J'ai vérifié les plans d'exécution de deux requêtes fonctionnellement équivalentes de ce type dans Oracle 10g :

core> select sta from zip group by sta;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH GROUP BY     |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

core> select distinct sta from zip;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH UNIQUE       |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

L'opération centrale est légèrement différente : "HASH GROUP BY" contre "HASH UNIQUE", mais les coûts estimés, etc. sont identiques. J'ai ensuite exécuté ces opérations avec le suivi activé et le nombre réel d'opérations était le même pour les deux (sauf que la deuxième opération n'a pas eu à effectuer de lecture physique en raison de la mise en cache).

Mais je pense que parce que les noms des opérations sont différents, l'exécution suivrait des chemins de code quelque peu différents et cela ouvre la possibilité de différences plus significatives.

Je pense que vous devriez préférer la syntaxe DISTINCT à cette fin. Ce n'est pas seulement une habitude, cela indique plus clairement le but de la requête.

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