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 myTbl
Ce que je suis curieux de savoir, 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 comprise.
SELECT c FROM myTbl UNION SELECT c FROM myTbl
et obtenir le même résultat ... Mais pourquoi compliquer les choses lorsque SELECT DISTINCT est si facile.GROUP BY
est bien plus ancien que «SELECT» etDISTINCT
suit select.DISTINCT
aboutit à sélectionner réellement le champ - c'est-à-dire que la valeur apparaîtra dans le jeu de résultats.GROUP BY
peut supprimer efficacement les doublons sans sélectionner le champ. Ceci est quelque peu hors de propos dans la plupart des cas, mais pourrait être exactement ce que vous voulez dans d'autres. Si vous finissez par utiliserGROUP BY
à la place deDISTINCT
, un commentaire explicatif dans le code est probablement justifié.Réponses:
La réponse de MusiGenesis est fonctionnellement la bonne en ce qui concerne votre question, comme indiqué; SQL Server est suffisamment intelligent pour se rendre compte que si vous utilisez "Grouper par" et que vous n'utilisez aucune fonction d'agrégation, ce que vous voulez dire par là est "Distinct" - et donc 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 également la réponse de Hank - le traitement cavalier de "Group By" et "Distinct" pourrait conduire à des accrochages pernicieux si vous n'y 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 vous posez des questions 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 l'autre non.
Un marteau peut parfois fonctionner pour enfoncer une vis, mais si vous avez un tournevis à portée de main, pourquoi vous embêter?
(aux fins de cette analogie,
Hammer : Screwdriver :: GroupBy : Distinct
etscrew => get list of unique values in a table column
)la source
GROUP BY
vous permet d' utiliser des fonctions d' agrégation, commeAVG
,MAX
,MIN
,SUM
etCOUNT
. D'un autre côté,DISTINCT
supprime simplement les doublons.Par exemple, si vous avez un tas d'enregistrements d'achat et que vous voulez savoir combien a été dépensé par chaque département, vous pouvez faire quelque chose comme:
Cela vous donnera une ligne par département, contenant le nom du département et la somme de toutes les
amount
valeurs de toutes les lignes pour ce département.la source
DISTINCT
+ une fonction d'agrégation? comme ceci:select distinct department, SUM(amount) from ...
Il n'y a aucune 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 est 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::::P11_QUESTION_ID:32961403234212
la source
Quelle est la différence d'un simple point de vue de la fonctionnalité de suppression des doublons
Outre le fait que, contrairement à
DISTINCT
,GROUP BY
permet d'agréger des données par groupe (qui a été mentionné par de nombreuses autres réponses), la différence la plus importante à mon avis est le fait que les deux opérations "se produisent" à deux étapes très différentes dans l' ordre logique des opérations qui sont exécutées dans uneSELECT
instruction .Voici les opérations les plus importantes:
FROM
(y comprisJOIN
,APPLY
, etc.)WHERE
GROUP BY
(peut supprimer les doublons)HAVING
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 influence ce qui peut être fait avec elle et comment elle influence les opérations suivantes. En particulier, le fait que l'
GROUP BY
opération "se passe avant" l'SELECT
opération (la projection) signifie que: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:
Lorsqu'il est exécuté sur la base de données Sakila , cela donne:
La même chose ne pouvait pas être obtenue avec
DISTINCT
facilement:Cette requête est "fausse" et donne quelque chose comme:
Ce n'est pas ce que nous voulions. L'
DISTINCT
opération "se produit après" la projection, nous ne pouvons donc plus supprimer lesDISTINCT
classements car la fonction fenêtre a déjà été calculée et projetée. Pour l'utiliserDISTINCT
, nous devons imbriquer cette partie de la requête:Note: Dans ce cas particulier, nous pourrions également utiliser
DENSE_RANK()
2. Il ne peut utiliser aucune valeur de la projection
L'un des inconvénients de SQL est parfois sa verbosité. 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.
Il s'agit d'un SQL non valide:
Ceci est valide (en répétant l'expression)
Ceci est également valable (imbriquer l'expression)
J'ai écrit sur ce sujet plus en profondeur dans un article de blog
la source
WHERE
mais peut-êtreGROUP BY
). En tout cas, je pense que c'est une mauvaise idée et je suggère de ne jamais utiliser cette fonctionnalité pour des raisons de portabilité et de maintenance. "Soudainement", cela ne fonctionnera plus, par exemple lors du crénelage d'une fonction d'agrégation ou d'une fonction de fenêtre.never using that feature for portability and maintenance reasons
!! d'accord à 100% ... et j'encourage maintenant votre blog aussi, excellent travail. À votre santé.À utiliser
DISTINCT
si vous souhaitez simplement supprimer les doublons. UtilisezGROUPY BY
si vous voulez appliquer les opérateurs globaux (MAX
,SUM
,GROUP_CONCAT
, ..., ou uneHAVING
clause).la source
Je m'attends à ce qu'il y ait la possibilité de différences subtiles dans leur exécution. J'ai vérifié les plans d'exécution pour deux requêtes fonctionnellement équivalentes dans ce sens dans Oracle 10g:
L'opération intermédiaire est légèrement différente: "HASH GROUP BY" contre "HASH UNIQUE", mais les coûts estimés, etc. sont identiques. Je les ai ensuite exécutés avec le suivi activé et le nombre d'opérations réel était le même pour 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 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 importantes.
Je pense que vous devriez préférer la syntaxe DISTINCT à cet effet. Ce n'est pas seulement une habitude, cela indique plus clairement le but de la requête.
la source
Pour la requête que vous avez publiée, elles sont identiques. Mais pour d'autres requêtes qui peuvent ne pas être vraies.
Par exemple, ce n'est pas la même chose que:
la source
J'ai lu tous les commentaires ci-dessus, mais je n'ai vu personne signaler la principale différence entre Group By et Distinct à part le bit d'agrégation.
Distinct renvoie toutes les lignes, puis les dédoublonne, tandis que Grouper par déduplique les lignes lorsqu'elles sont lues par l'algorithme une par une.
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:
S'il y a 10 noms dans le tableau où 1 est un doublon d'un autre, la première requête renvoie 10 lignes tandis que la deuxième requête renvoie 9 lignes.
La raison est ce que j'ai dit ci-dessus pour qu'ils puissent se comporter différemment!
la source
Name
dans la deuxième requête, ledistinct
mot clé s'applique à la fois aux colonnesName
et à votreROW_NUMBER()
colonne dans laselect
clause de la première requête. Si vous aviez également regroupé par la première colonne dans la deuxième requête, les requêtes auraient renvoyé les mêmes résultats.order of execution
des clauses SQL qui est (au sens général)FROM and ON (joins)
,WHERE
,GROUP BY
,HAVING
,SELECT
,DISTINCT
,ORDER BY
, deLIMIT / OFFSET / TOP
sorte que la seconde requête les noms sont réduits en nombre par groupe par et plus tard le row_number () est appliqué résultant en une rangée par nom unique. Dans la première requête, row_number () est appliqué avant que le distinct soit appliqué, et en raison de la nature de la fonction row_number (), chaque ligne obtient un entier unique, donc chaque ligne est renvoyée même s'il y a des valeurs de nom répété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 pouvez pas utiliser les fonctions d'agrégation avec DISTINCT.
la source
Ils ont une sémantique différente, même s'ils ont des résultats équivalents sur vos données particulières.
la source
GROUP BY a une signification très spécifique qui est distincte (heh) de la fonction DISTINCT.
GROUP BY entraîne le regroupement des résultats de la requête à l'aide de l'expression choisie, des fonctions d'agrégation peuvent ensuite être appliquées et celles-ci agissent sur chaque groupe, plutôt que sur l'ensemble des résultats.
Voici un exemple qui pourrait vous aider:
Étant donné une table qui ressemble à ceci:
Cette requête:
Produira une sortie comme celle-ci:
Ce qui est évidemment très différent de l'utilisation de DISTINCT. Si vous voulez grouper vos résultats, utilisez GROUP BY, si vous voulez juste une liste unique d'une colonne spécifique, utilisez DISTINCT. Cela donnera à votre base de données une chance d'optimiser la requête selon vos besoins.
la source
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 réduire les millisecondes des requêtes, et je dois souligner que le temps du développeur est beaucoup plus cher que le temps de l'ordinateur.
la source
Si vous utilisez un GROUP BY sans fonction d'agrégation, il sera traité en interne comme DISTINCT, donc dans ce cas il n'y a pas de différence entre GROUP BY et DISTINCT.
Mais lorsque la clause DISTINCT vous est fournie, il vaut mieux l'utiliser pour rechercher vos enregistrements uniques, car l'objectif de GROUP BY est de réaliser l'agrégation.
la source
group by est utilisé dans les opérations d'agrégation - comme lorsque vous voulez obtenir un nombre de Bs décomposé par la colonne C
distinct est ce que cela ressemble - vous obtenez des lignes uniques.
Dans SQL Server 2005, il semble que l'optimiseur de requêtes soit en mesure d'optimiser la différence dans les exemples simplistes que j'ai exécutés. Je ne sais pas si vous pouvez compter sur cela dans toutes les situations.
la source
Dans cette requête particulière, il n'y a aucune différence. Mais, bien sûr, si vous ajoutez des colonnes agrégées, vous devrez utiliser le regroupement par.
la source
Dans la perspective Teradata :
D'un point de vue d'ensemble de résultats, peu importe si vous utilisez DISTINCT ou GROUP BY dans Teradata. L'ensemble de réponses sera le même.
Du point de vue des performances, ce n'est pas pareil.
Pour comprendre ce qui affecte les 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 redistribuées immédiatement sans aucune pré-agrégation, tandis que dans le cas de GROUP BY, dans une première étape, une pré-agrégation est effectuée et ce n'est qu'alors que les valeurs uniques sont redistribuées entre les AMP.
Ne pensez pas maintenant que GROUP BY est toujours meilleur du point de vue des performances. Lorsque vous avez plusieurs valeurs différentes, l'étape de pré-agrégation de GROUP BY n'est pas très efficace. Teradata doit trier les données pour supprimer les doublons. Dans ce cas, il peut être préférable de procéder à la redistribution en premier, c'est-à-dire d'utiliser l'instruction DISTINCT. Ce n'est que s'il existe de nombreuses valeurs en double que l'instruction GROUP BY est probablement le meilleur choix, car seulement une fois l'étape de déduplication effectuée, après redistribution.
En bref, DISTINCT vs GROUP BY dans Teradata signifie:
GROUP BY -> pour de nombreux doublons DISTINCT -> pas ou quelques doublons seulement. Parfois, lorsque vous utilisez DISTINCT, vous manquez d'espace de spoule sur un AMP. La raison en est que la redistribution a lieu immédiatement, et une asymétrie pourrait entraîner un manque d'espace pour les AMP.
Si cela se produit, vous avez probablement plus de chances avec GROUP BY, car les doublons sont déjà supprimés dans une première étape et moins de données sont déplacées entre les AMP.
la source
Teradata
?Du point de vue «SQL le langage», les deux constructions sont équivalentes et celle 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 prévenant pour 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 ce «GROUPE PAR est pour les agrégats» n'est pas le bon accent. Les gens doivent savoir que la fonction définie (MAX, MIN, COUNT, etc.) peut être omise afin qu'ils puissent comprendre l'intention du codeur lorsqu'elle l'est.
L'optimiseur idéal reconnaîtra les constructions SQL équivalentes et choisira toujours le plan idéal en conséquence. Pour votre moteur SQL réel de choix, vous devez tester :)
PS note que la position du mot-clé DISTINCT dans la clause select peut produire des résultats différents, par exemple le contraste:
la source
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:
Ce qui montrerait la somme de toutes les transactions pour chaque personne.
la source
Je sais que c'est un vieux poste. Mais il arrive que j'avais une requête qui utilisait le groupe juste pour renvoyer des valeurs distinctes lors de l'utilisation de cette requête dans les rapports toad 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 lors de l'utilisation de la version précédente, cela a pris environ 5 minutes.
La solution était de changer le groupe et d'utiliser DISTINCT et maintenant le rapport s'exécute en 30 secondes environ.
J'espère que cela est utile pour quelqu'un avec la même situation.
la source
En termes d'utilisation, GROUP BY est utilisé pour regrouper les lignes que vous souhaitez calculer. DISTINCT ne fera aucun calcul. Il n'affichera aucune ligne en double.
J'ai toujours utilisé DISTINCT si je veux présenter des données sans doublons.
Si je veux faire des calculs comme résumer la quantité totale de mangues, j'utiliserai GROUP BY
la source
La façon dont j'ai toujours compris, c'est que l'utilisation de distinct est identique au regroupement par chaque champ que vous avez sélectionné dans l'ordre dans lequel vous les avez sélectionnés.
c'est à dire:
est le même que:
la source
L'efficacité fonctionnelle est totalement différente. Si vous ne souhaitez sélectionner que la "valeur de retour", sauf celle en double, il est préférable d'utiliser distinct plutôt que de grouper par. Parce que "regrouper par" inclut (tri + suppression), "distinct" inclut (suppression)
la source
Dans Hive (HQL), group by peut être bien 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/surprises-assumptions-group-by-distinct .
la source
Parfois, ils peuvent vous donner les mêmes résultats, mais ils sont destinés à être utilisés dans un sens / cas différent. La principale différence réside dans la syntaxe.
Notez attentivement l'exemple ci-dessous.
DISTINCT
est utilisé pour filtrer l'ensemble de valeurs en double. (6, cs, 9.1) et (1, cs, 5.5) sont deux ensembles différents. Donc,DISTINCT
va afficher les deux lignes tandis queGROUP BY Branch
va afficher un seul ensemble.Parfois, les résultats qui peuvent être obtenus par
GROUP BY
clause ne peuvent pas être obtenusDISTINCT
sans utiliser une clause ou des conditions supplémentaires. Par exemple, dans le cas ci-dessus.Pour obtenir le même résultat que
DISTINCT
vous devez passer tous les noms de colonne dans laGROUP BY
clause comme ci-dessous. Alors voyez la différence syntaxique. Vous devez avoir des connaissances sur tous les noms de colonne pour utiliser laGROUP BY
clause dans ce cas.J'ai également remarqué que
GROUP BY
les résultats sont affichés par ordre croissant par défaut, ce quiDISTINCT
n'est pas le cas. Mais je n'en suis pas sûr. Il peut être différent selon le fournisseur.Source: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by
la source
Généralement, nous pouvons utiliser
DISTINCT
pour éliminer les doublons sur une colonne spécifique dans le tableau.Exemple :
la source
Il n'y a pas de différence significative entre group by et clause distincte à l'exception de l'utilisation de fonctions d'agrégation. Les deux peuvent être utilisés pour distinguer les valeurs, mais si en termes de performances, le groupe est meilleur. Lorsqu'un mot clé distinct est utilisé, il utilise en interne une opération de tri qui peut être affichée dans le plan d'exécution.
Essayez un exemple simple
Déclarez la table @tmpresult (Id tinyint)
Insérer dans @tmpresult Sélectionner 5 Union tout Sélectionner 2 Union tout Sélectionner 3 Union tout Sélectionner 4
Sélectionner un identifiant distinct dans @tmpresult
la source