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

J’ai appris quelque chose de simple à propos de SQL l’autre jour:

SELECT c FROM myTbl GROUP BY C 

A le même résultat que:

 SELECT DISTINCT C FROM myTbl 

Ce dont je suis curieux, y a-t-il quelque chose de différent dans la façon dont un moteur SQL traite la commande ou est-ce vraiment la même chose?

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

EDIT: Ce n’est pas une question sur les agrégats. L’utilisation de GROUP BY avec des fonctions d’agrégation est bien comprise.

    La réponse de MusiGenesis est fonctionnellement la réponse correcte par rapport à votre question comme indiqué; SQL Server est suffisamment intelligent pour comprendre que si vous utilisez “Group By” et n’utilisez aucune fonction d’agrégat, alors vous voulez dire “Distinct” – et par conséquent il génère un plan d’exécution comme si vous aviez simplement utilisé “Distinct”. . ”

    Cependant, je pense qu’il est important de noter que la réponse de Hank – traitement cavalier de “Group By” et “Distinct” pourrait conduire à des pièges 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 d’agrégats, car vous vous interrogez sur la différence fonctionnelle entre deux mots clés de requête SQL, l’un étant destiné aux agrégats et l’autre non.

    Un marteau peut parfois conduire à la vis, mais si vous avez un tournevis à scope de main, pourquoi s’en préoccuper?

    (… pour les besoins de cette analogie, Hammer : Screwdriver :: GroupBy : Distinct et screw => get list of unique values in a table column )

    GROUP BY vous permet d’utiliser des fonctions d’agrégation, telles que AVG , MAX , MIN , SUM et COUNT . D’autre part, DISTINCT supprime simplement les doublons.

    Par exemple, si vous avez un tas d’enregistrements d’achat et que vous voulez savoir combien chaque département a dépensé, vous pouvez faire quelque chose comme:

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

    Cela vous donnera une ligne par département, contenant le nom du département et la sum de toutes les valeurs de amount dans toutes les lignes pour ce département.

    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 y a-t-il une différence s’il y a des sous-requêtes 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 pas de différence (style Oracle):

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

    Utilisez DISTINCT si vous souhaitez simplement supprimer les doublons. Utilisez GROUPY BY si vous souhaitez appliquer des opérateurs agrégés ( MAX , SUM , GROUP_CONCAT , … ou une clause HAVING ).

    Quelle est la différence entre un simple sharepoint vue de la fonctionnalité de suppression des doublons?

    Mis à part le fait que GROUP BY permet, contrairement à DISTINCT , d’agréger des données par groupe (ce qui a été mentionné par de nombreuses autres réponses), la différence la plus importante à mon avis réside dans le fait que les deux opérations “se déroulent” l’ ordre logique des opérations exécutées dans une SELECT .

    Voici les opérations les plus importantes:

    • FROM (y compris JOIN , APPLY , etc.)
    • WHERE
    • GROUP BY (peut supprimer les doublons)
    • Agrégations
    • HAVING
    • Fonctions de fenêtre
    • SELECT
    • DISTINCT (peut supprimer les doublons)
    • UNION , INTERSECT , EXCEPT (peut supprimer les doublons)
    • ORDER BY
    • OFFSET
    • LIMIT

    Comme vous pouvez le voir, l’ordre logique de chaque opération influe sur ce qui peut être fait et sur son influence sur les opérations ultérieures. En particulier, le fait que l’opération GROUP BY “se produise avant” l’opération SELECT (la projection) signifie que:

    1. Cela ne dépend pas de la projection (ce qui peut être un avantage)
    2. Il ne peut utiliser aucune valeur de la projection (ce qui peut être un inconvénient)

    1. Cela ne dépend pas de la projection

    Un exemple où ne pas dépendre de la projection est utile est si vous voulez calculer des fonctions de fenêtre sur des valeurs distinctes:

     SELECT rating, row_number() OVER (ORDER BY rating) AS rn FROM film GROUP BY rating 

    Lorsqu’il est exécuté sur la firebase database Sakila , cela donne:

     rating rn ----------- G 1 NC-17 2 PG 3 PG-13 4 R 5 

    La même chose n’a pas pu être réalisée avec DISTINCT facilement:

     SELECT DISTINCT rating, row_number() OVER (ORDER BY rating) AS rn FROM film 

    Cette requête est “erronée” et produit quelque chose comme:

     rating rn ------------ G 1 G 2 G 3 ... G 178 NC-17 179 NC-17 180 ... 

    Ce n’est pas ce que nous voulions. L’opération DISTINCT “se produit après” la projection, nous ne pouvons donc plus supprimer les évaluations DISTINCT car la fonction de fenêtre était déjà calculée et projetée. Pour utiliser DISTINCT , il faudrait imbriquer cette partie de la requête:

     SELECT rating, row_number() OVER (ORDER BY rating) AS rn FROM ( SELECT DISTINCT rating FROM film ) f 

    Note: Dans ce cas particulier, nous pourrions également utiliser DENSE_RANK()

     SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn FROM film 

    2. Il ne peut utiliser aucune valeur de la projection

    L’un des inconvénients de SQL est sa verbosité parfois. Pour la même raison que ce que nous avons vu auparavant (à savoir l’ordre logique des opérations), nous ne pouvons pas “facilement” grouper par quelque chose que nous projetons.

    Ceci est invalide SQL:

     SELECT first_name || ' ' || last_name AS name FROM customer GROUP BY name 

    Ceci est valide (répétition de l’expression)

     SELECT first_name || ' ' || last_name AS name FROM customer GROUP BY first_name || ' ' || last_name 

    Ceci est valide aussi (imbriquer l’expression)

     SELECT name FROM ( SELECT first_name || ' ' || last_name AS name FROM customer ) c GROUP BY name 

    J’ai écrit sur ce sujet plus en détail dans un article de blog

    Je pense qu’il existe une possibilité de différences subtiles dans leur exécution. J’ai vérifié les plans d’exécution de deux requêtes équivalentes sur le plan fonctionnel 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 intermédiaire est légèrement différente: “HASH GROUP BY” vs “HASH UNIQUE”, mais les coûts estimés, etc. sont identiques. Je les ai ensuite exécutés avec le suivi et le nombre d’opérations réelles était le même pour tous les deux (sauf que le second n’avait pas à effectuer de lectures physiques en raison de la mise en cache).

    Mais je pense que parce que les noms d’opération 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 juste une habitude, cela indique plus clairement le but de la requête.

    Pour la requête que vous avez publiée, elles sont identiques. Mais pour d’autres requêtes, cela peut ne pas être vrai.

    Par exemple, ce n’est pas la même chose que:

     SELECT C FROM myTbl GROUP BY C, D 

    Ils ont une sémantique différente, même s’ils ont des résultats équivalents sur vos données.

    Si vous utilisez DISTINCT avec plusieurs colonnes, le jeu de résultats ne sera pas groupé comme il le fera avec GROUP BY et vous ne pourrez pas utiliser les fonctions d’agrégation avec DISTINCT.

    J’ai lu tous les commentaires ci-dessus mais je n’ai vu personne souligner la principale différence entre Group By et Distinct en dehors du bit d’agrégation.

    Distinct renvoie toutes les lignes, puis les déduploie, tandis que Group By dés-dédupliquera les lignes au fur et à mesure qu’elles seront lues par l’algorithme.

    Cela signifie qu’ils peuvent produire des résultats différents!

    Par exemple, les codes ci-dessous génèrent des résultats différents:

     SELECT distinct ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable SELECT ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable GROUP BY Name 

    S’il y a 10 noms dans la table dont 1 est une copie d’un autre, la première requête renvoie 10 lignes alors que la seconde renvoie 9 lignes.

    La raison en est ce que j’ai dit ci-dessus pour qu’ils puissent se comporter différemment!

    GROUP BY a une signification très spécifique distincte de la fonction DISTINCT.

    GROUP BY provoque le regroupement des résultats de la requête en utilisant l’expression choisie, les fonctions d’agrégat peuvent alors être appliquées, et celles-ci agiront sur chaque groupe, plutôt que sur le jeu de résultats entier.

    Voici un exemple qui pourrait aider:

    Étant donné un tableau qui ressemble à ceci:

     name ------ barry dave bill dave dave barry john 

    Cette requête:

     SELECT name, count(*) AS count FROM table GROUP BY name; 

    Produira une sortie comme celle-ci:

     name count ------------- barry 2 dave 3 bill 1 john 1 

    Ce qui est évidemment très différent de l’utilisation de DISTINCT. Si vous souhaitez regrouper vos résultats, utilisez GROUP BY si vous souhaitez simplement une liste unique d’une colonne spécifique, utilisez DISTINCT. Cela donnera à votre firebase database une chance d’optimiser la requête pour vos besoins.

    Si vous utilisez un GROUP BY sans fonction d’agrégat, il sera traité en interne comme DISTINCT. Dans ce cas, il n’y a pas de différence entre GROUP BY et DISTINCT.

    Toutefois, lorsque la clause DISTINCT vous est fournie, mieux vaut l’utiliser pour trouver vos enregistrements uniques, car l’objective de GROUP BY est d’obtenir l’agrégation.

    group by est utilisé dans les opérations d’agrégat – comme lorsque vous voulez obtenir un décompte de Bs ventilé par colonne C

     select C, count(B) from myTbl group by C 

    distinct est ce que cela ressemble – vous obtenez des lignes uniques.

    Dans sql server 2005, l’optimiseur de requêtes semble pouvoir optimiser la différence entre les exemples simplistes que j’ai utilisés. Je ne sais pas si vous pouvez compter sur cela dans toutes les situations.

    Veuillez ne pas utiliser GROUP BY lorsque vous voulez dire DISTINCT, même s’ils fonctionnent de la même manière. Je suppose que vous essayez de rayer les millisecondes des requêtes, et je dois souligner que le temps de développement est beaucoup plus coûteux que le temps passé sur un ordinateur.

    Dans cette requête particulière, il n’y a pas de différence. Mais, bien sûr, si vous ajoutez des colonnes agrégées, vous devrez utiliser group by.

    Du sharepoint vue du langage SQL, les deux concepts sont équivalents et celui que vous choisissez est l’un de ces choix de style de vie que nous devons tous faire. Je pense qu’il y a de bonnes raisons pour que DISTINCT soit plus explicite (et donc plus attentif à la personne qui héritera de votre code, etc.) mais cela ne signifie pas que la construction GROUP BY est un choix invalide.

    Je pense que cette ‘GROUP BY est pour les agrégats’ est le mauvais accent. Les gens doivent être conscients que la fonction définie (MAX, MIN, COUNT, etc.) peut être omise afin de pouvoir comprendre l’intention du codeur.

    L’optimiseur idéal reconnaîtra les constructions SQL équivalentes et choisira toujours le plan idéal en conséquence. Pour votre vrai moteur SQL de choix, vous devez tester 🙂

    PS notez que la position du mot-clé DISTINCT dans la clause select peut donner des résultats différents, par exemple le contraste:

     SELECT COUNT(DISTINCT C) FROM myTbl; SELECT DISTINCT COUNT(C) FROM myTbl; 

    Dans la perspective de Teradata :

    Du sharepoint vue du jeu de résultats, peu importe si vous utilisez DISTINCT ou GROUP BY dans Teradata. L’ensemble de réponses sera le même.

    Du sharepoint vue de la performance, ce n’est pas la même chose.

    Pour comprendre l’impact des performances, vous devez savoir ce qui se passe sur Teradata lors de l’exécution d’une instruction avec DISTINCT ou GROUP BY.

    Dans le cas de DISTINCT, les lignes sont immédiatement redissortingbuées sans qu’aucune pré-agrégation ait lieu, alors que dans le cas de GROUP BY, une pré-agrégation est effectuée dans un premier temps et seules les valeurs uniques sont redissortingbuées aux AMP.

    Ne pensez pas que GROUP BY est toujours meilleur du sharepoint vue de la performance. Lorsque vous avez plusieurs valeurs différentes, l’étape de pré-agrégation de GROUP BY n’est pas très efficace. Teradata doit sortinger les données pour supprimer les doublons. Dans ce cas, il peut être préférable de commencer par la redissortingbution, c’est-à-dire d’utiliser l’instruction DISTINCT. Seulement s’il y a beaucoup de valeurs en double, l’instruction GROUP BY est probablement le meilleur choix, car une fois que l’étape de déduplication a eu lieu, après la redissortingbution.

    En bref, DISTINCT vs GROUP BY dans Teradata signifie:

    GROUP BY -> pour de nombreux doublons DISTINCT -> aucun ou quelques doublons seulement. Parfois, lorsque vous utilisez DISTINCT, vous êtes à court d’espace de spoule sur un AMP. La raison en est que la redissortingbution a lieu immédiatement et que l’inclinaison pourrait entraîner un manque d’espace des AMP.

    Si cela se produit, vous avez probablement une meilleure chance avec GROUP BY, car les doublons sont déjà supprimés dans un premier temps, et moins de données sont déplacées à travers les AMP.

    Vous ne le remarquez que parce que vous sélectionnez une seule colonne.

    Essayez de sélectionner deux champs et voyez ce qui se passe.

    Group By est destiné à être utilisé comme ceci:

     SELECT name, SUM(transaction) FROM myTbl GROUP BY name 

    Qui montrerait la sum de toutes les transactions pour chaque personne.

    Je sais que c’est un ancien message. Mais il se trouve que j’avais une requête qui utilisait group by juste pour renvoyer des valeurs distinctes lorsque vous utilisiez cette requête dans les rapports crapaud et oracle tout fonctionnait bien, je veux dire un bon temps de réponse. Lorsque nous avons migré d’Oracle 9i vers 11g, le temps de réponse dans Toad était excellent, mais dans le rapport, il a fallu environ 35 minutes pour terminer le rapport lorsque la version précédente a pris environ 5 minutes.

    La solution consistait à changer le groupe par DISTINCT et à utiliser DISTINCT. Le rapport est maintenant exécuté dans environ 30 secondes.

    J’espère que cela est utile pour quelqu’un avec la même situation.

    Comme je l’ai toujours compris, l’utilisation de distinct est la même chose que le regroupement par domaine que vous avez sélectionné dans l’ordre que vous avez sélectionné.

    c’est à dire:

     select distinct a, b, c from table; 

    est le même que:

     select a, b, c from table group by a, b, c 

    J’avais cette question auparavant, je dois append trois colonnes de ma table de 4 millions de lignes (les trois colonnes dans une nouvelle colonne d’une nouvelle table) mais seulement les différentes.

    J’ai donc exécuté ma procédure stockée qui contient cette requête avec la méthode ‘group by’ et cela a pris 32 minutes. Ensuite, je l’ai à nouveau exécuté, mais avec une méthode «distincte» et cela a pris 25 minutes.

    C’est le même résultat, mais c’était un peu plus rapide avec la 2ème méthode

    L’efficacité Funtional est totalement différente. Si vous souhaitez sélectionner uniquement la “valeur de retour” sauf la valeur en double, use distinct vaut mieux que group by. Parce que “group by” inclut (sorting + suppression), “distinct” inclut (suppression)

    Dans Hive (HQL), le group by peut être beaucoup plus rapide que distinct, car le premier ne nécessite pas de comparer tous les champs de la table. Voir https://sqlperformance.com/2017/01/t-sql-queries/sursockets-assumptions-group-by-distinct .

    Il n’y a pas de différence significative entre la clause group by et distinct sauf l’utilisation des fonctions d’agrégat. Les deux peuvent être utilisés pour distinguer les valeurs mais si, du sharepoint vue de la performance, le groupe by est meilleur. Lorsqu’un mot clé distinct est utilisé, en interne, il a utilisé une opération de sorting qui peut être vue dans le plan d’exécution.

    Essayez un exemple simple

    Déclarez la table @tmpresult (Id tinyint)

    Insérez dans @tmpresult Sélectionnez 5 Union all Sélectionnez 2 Union all Sélectionnez 3 Union all Sélectionnez 4

    Sélectionnez un identifiant distinct de @tmpresult