Is er een verschil tussen GROUP BY en DISTINCT

Ik heb onlangs iets eenvoudigs geleerd over SQL:

SELECT c FROM myTbl GROUP BY C

Heeft hetzelfde resultaat als:

SELECT DISTINCT C FROM myTbl

Waar ik nieuwsgierig naar ben, is er iets anders in de manier waarop een SQL-engine de opdracht verwerkt, of zijn ze echt hetzelfde?

Persoonlijk geef ik de voorkeur aan de duidelijke syntaxis, maar ik weet zeker dat het meer uit gewoonte is dan iets anders.

EDIT: dit is geen vraag over aggregaten. Het gebruik van GROUP BYmet geaggregeerde functies is bekend.


Antwoord 1, autoriteit 100%

MusiGenesis‘ antwoord is functioneel de juiste met betrekking tot uw vraag zoals vermeld; de SQL Server is slim genoeg om te beseffen dat als je “Group By” gebruikt en geen geaggregeerde functies gebruikt, je eigenlijk “Distinct” bedoelt – en daarom genereert het een uitvoeringsplan alsof je gewoon “Distinct .”

Ik denk echter dat het belangrijk is om Hank op te merken ‘s reactie ook – arrogante behandeling van “Group By” en “Distinct” kan leiden tot een aantal verderfelijke problemen als je niet oppast. Het is niet helemaal correct om te zeggen dat dit “geen vraag over aggregaten” is, omdat u vraagt ​​naar het functionele verschil tussen twee SQL-query-sleutelwoorden, waarvan er één bedoeld is om te worden gebruikt met aggregatenen één waarvan niet.

Een hamer kan soms werken om een ​​schroef in te draaien, maar als je een schroevendraaier bij de hand hebt, waarom zou je je dan druk maken?

(voor de toepassing van deze analogie, Hammer : Screwdriver :: GroupBy : Distincten screw => get list of unique values in a table column)


Antwoord 2, autoriteit 57%

Met

GROUP BYkunt u statistische functies gebruiken, zoals AVG, MAX, MIN, SUMen COUNT.
Aan de andere kant verwijdert DISTINCTalleen duplicaten.

Als u bijvoorbeeld een aantal aankoopgegevens heeft en u wilt weten hoeveel er door elke afdeling is uitgegeven, kunt u zoiets doen als:

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

Hierdoor krijgt u één rij per afdeling, met daarin de afdelingsnaam en de som van alle amount-waarden in alle rijen voor die afdeling.


Antwoord 3, autoriteit 23%

Wat is het verschil met louter het oogpunt van dubbele verwijderingsfunctionaliteit

Afgezien van het feit dat in tegenstelling tot DISTINCT, GROUP BYhet mogelijk maakt om gegevens per groepsamen te voegen (wat door veel andere antwoorden is genoemd) , is het belangrijkste verschil naar mijn mening het feit dat de twee operaties “gebeuren” in twee heel verschillende stappen in de logische volgorde van bewerkingen die worden uitgevoerd in een SELECT-instructie.

Dit zijn de belangrijkste bewerkingen:

  • FROM(inclusief JOIN, APPLY, enz.)
  • WHERE
  • GROUP BY(kan duplicaten verwijderen)
  • Aggregaties
  • HAVING
  • Vensterfuncties
  • SELECT
  • DISTINCT(kan duplicaten verwijderen)
  • UNION, INTERSECT, EXCEPT(kan duplicaten verwijderen)
  • ORDER BY
  • OFFSET
  • LIMIT

Zoals u kunt zien, is de logische volgorde van elke bewerking van invloed op wat ermee kan worden gedaan en hoe deze de daaropvolgende bewerkingen beïnvloedt. In het bijzonder het feit dat de GROUP BYbewerking “gebeurt voor”de SELECTbewerking (de projectie) betekent dat:

  1. Het hangt niet af van de projectie (wat een voordeel kan zijn)
  2. Het kan geen waarden uit de projectie gebruiken (wat een nadeel kan zijn)

1. Het hangt niet af van de projectie

Een voorbeeld waarbij niet afhankelijk zijn van de projectie handig is, is als u vensterfuncties op verschillende waarden wilt berekenen:

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

Als het wordt vergeleken met de Sakila-database, levert dit het volgende op:

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

Hetzelfde kon niet gemakkelijk worden bereikt met DISTINCT:

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

Die zoekopdracht is “fout” en levert zoiets op als:

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

Dit is niet wat we wilden. De DISTINCTbewerking “gebeurt na”de projectie, dus we kunnen DISTINCTbeoordelingen niet langer verwijderen omdat de vensterfunctie al berekend en geprojecteerd was. Om DISTINCTte gebruiken, moeten we dat deel van de zoekopdracht nesten:

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

Side-note: In dit specifieke geval kunnen we ook DENSE_RANK()

gebruiken

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

2. Het kan geen waarden uit de projectie gebruiken

Een van de nadelen van SQL is soms de breedsprakigheid. Om dezelfde reden als wat we eerder hebben gezien (namelijk de logische volgorde van bewerkingen), kunnen we ons niet “gemakkelijk” groeperen op iets dat we projecteren.

Dit is een ongeldige SQL:

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

Dit is geldig (herhaling van de uitdrukking)

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

Dit is ook geldig (de uitdrukking nesten)

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

Ik heb meer over dit onderwerp geschreven in een blogpost


Antwoord 4, autoriteit 17%

Er is geen verschil(tenminste in SQL Server). Beide zoekopdrachten gebruiken hetzelfde uitvoeringsplan.

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

Misschien is er iseen verschil, als er subquery’s bij betrokken zijn:

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

Er is geen verschil(Oracle-stijl):

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


Antwoord 5, autoriteit 12%

Gebruik DISTINCTals je alleen duplicaten wilt verwijderen. Gebruik GROUPY BYals u statistische operatoren (MAX, SUM, GROUP_CONCAT, … of een HAVING-clausule).


Antwoord 6, autoriteit 7%

Ik verwacht dat er de mogelijkheid is voor subtiele verschillen in hun uitvoering.
Ik controleerde de uitvoeringsplannen voor twee functioneel equivalente queries langs deze lijnen in 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 |
---------------------------------------------------------------------------

De middelste bewerking is iets anders: “HASH GROUP BY” versus “HASH UNIQUE”, maar de geschatte kosten enz. zijn identiek. Ik heb deze vervolgens uitgevoerd met tracering ingeschakeld en de werkelijke bewerkingen waren voor beide hetzelfde (behalve dat de tweede geen fysieke uitlezingen hoefde te doen vanwege caching).

Maar ik denk dat, omdat de namen van de bewerkingen anders zijn, de uitvoering enigszins andere codepaden zou volgen en dat de mogelijkheid van grotere verschillen opengaat.

Ik denk dat je voor dit doel de voorkeur moet geven aan de DISTINCT-syntaxis. Het is niet alleen een gewoonte, het geeft duidelijker het doel van de zoekopdracht aan.


Antwoord 7, autoriteit 5%

Voor de zoekopdracht die je hebt gepost, zijn ze identiek. Maar voor andere vragen is dat misschien niet waar.

Het is bijvoorbeeld niet hetzelfde als:

SELECT C FROM myTbl GROUP BY C, D

Antwoord 8, autoriteit 5%

Ik heb alle bovenstaande opmerkingen gelezen, maar ik heb niemand gezien die wees op het belangrijkste verschil tussen Group By en Distinct, afgezien van het aggregatiegedeelte.

Distinct retourneert alle rijen en dedupliceert ze, terwijl Group By de rijen dedupliceert zoals ze door het algoritme één voor één worden gelezen.

Dit betekent dat ze verschillende resultaten kunnen opleveren!

De onderstaande codes genereren bijvoorbeeld verschillende resultaten:

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

Als er 10 namen in de tabel staan ​​waarvan er 1 een duplicaat is van een andere, dan retourneert de eerste zoekopdracht 10 rijen, terwijl de tweede zoekopdracht 9 rijen retourneert.

De reden is wat ik hierboven zei, zodat ze zich anders kunnen gedragen!


Antwoord 9, autoriteit 4%

Als u DISTINCT met meerdere kolommen gebruikt, wordt de resultatenset niet gegroepeerd zoals bij GROUP BY, en kunt u geen statistische functies gebruiken met DISTINCT.


Antwoord 10, autoriteit 2%

Ze hebben verschillende semantiek, zelfs als ze gelijkwaardige resultaten hebben voor uw specifieke gegevens.


Antwoord 11, autoriteit 2%

GROUP BY heeft een heel specifieke betekenis die verschilt (heh) van de functie DISTINCT.

GROUP BY zorgt ervoor dat de queryresultaten worden gegroepeerd met behulp van de gekozen expressie, waarna statistische functies kunnen worden toegepast, en deze werken op elke groep in plaats van op de volledige resultatenset.

Hier is een voorbeeld dat kan helpen:

Gegeven een tabel die er als volgt uitziet:

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

Deze zoekopdracht:

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

Zal als volgt uitvoer produceren:

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

Wat natuurlijk heel anders is dan het gebruik van DISTINCT. Als u uw resultaten wilt groeperen, gebruikt u GROUP BY, als u alleen een unieke lijst van een specifieke kolom wilt, gebruikt u DISTINCT. Dit geeft uw database de kans om de zoekopdracht voor uw behoeften te optimaliseren.


Antwoord 12, autoriteit 2%

Als u een GROUP BY gebruikt zonder enige aggregatiefunctie, wordt deze intern behandeld als DISTINCT, dus in dit geval is er geen verschil tussen GROUP BY en DISTINCT.

Maar als u een DISTINCT-clausule krijgt, kunt u deze beter gebruiken voor het vinden van uw unieke records, omdat het doel van GROUP BY aggregatie is.


Antwoord 13, autoriteit 2%

Gebruik GROUP BY niet als je DISTINCT bedoelt, ook al werken ze toevallig hetzelfde. Ik neem aan dat je milliseconden probeert te besparen op zoekopdrachten, en ik moet je erop wijzen dat ontwikkelaarstijd orden van grootte duurder is dan computertijd.


Antwoord 14, autoriteit 2%

In Teradata-perspectief:

Vanuit het oogpunt van resultaatset maakt het niet uit of u DISTINCT of GROUP BY in Teradata gebruikt. De antwoordenset zal hetzelfde zijn.

Vanuit het oogpunt van prestaties is het niet hetzelfde.

Om te begrijpen wat van invloed is op de prestaties, moet u weten wat er op Teradata gebeurt bij het uitvoeren van een instructie met DISTINCT of GROUP BY.

In het geval van DISTINCT worden de rijen onmiddellijk herverdeeld zonder dat er preaggregatie plaatsvindt, terwijl in het geval van GROUP BY in een eerste stap een preaggregatie wordt gedaan en pas daarna worden de unieke waarden herverdeeld over de AMP’s.

p>

Denk nu niet dat GROUP BY vanuit prestatieoogpunt altijd beter is. Wanneer u veel verschillende waarden heeft, is de preaggregatiestap van GROUP BY niet erg efficiënt. Teradata moet de gegevens sorteren om duplicaten te verwijderen. In dit geval kan het beter zijn om eerst de herverdeling te doen, d.w.z. gebruik de instructie DISTINCT. Alleen als er veel dubbele waarden zijn, is de GROUP BY-instructie waarschijnlijk de betere keuze, omdat de deduplicatiestap pas plaatsvindt, na herverdeling.

Kortom, DISTINCT vs. GROUP BY in Teradata betekent:

GROEPEREN OP -> voor veel duplicaten
VERSCHILLEND -> geen of slechts enkele duplicaten.
Soms, wanneer u DISTINCT gebruikt, heeft u onvoldoende spoelruimte op een AMP. De reden is dat herverdeling onmiddellijk plaatsvindt, en scheeftrekken kan ertoe leiden dat AMP’s geen ruimte meer hebben.

Als dit gebeurt, heb je waarschijnlijk meer kans met GROUP BY, omdat duplicaten al in een eerste stap worden verwijderd en er minder gegevens tussen de AMP’s worden verplaatst.


Antwoord 15

groeperen op wordt gebruikt in geaggregeerde bewerkingen, bijvoorbeeld wanneer u een telling van B’s wilt krijgen, uitgesplitst naar kolom C

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

verschillend is hoe het klinkt — je krijgt unieke rijen.

In sql server 2005 lijkt het erop dat de query-optimizer het verschil in de simplistische voorbeelden die ik heb gebruikt, kan optimaliseren. Ik weet echter niet of je daar in alle situaties op kunt rekenen.


Antwoord 16

In die specifieke zoekopdracht is er geen verschil. Maar als u geaggregeerde kolommen toevoegt, moet u natuurlijk group by gebruiken.


Antwoord 17

Vanaf een ‘SQL Het taal’ perspectief is de twee constructies equivalent en welke die je kiest, is een van die ‘lifestyle’ keuzes die we allemaal moeten maken. Ik denk dat er een goed geval is om onderscheiden explicieter te zijn (en is daarom niet attent voor de persoon die uw code zal erven), maar dat betekent niet dat de groep per constructie een ongeldige keuze is.

Ik denk dat deze ‘groep door is voor aggregaten’ de verkeerde nadruk is. Folk moet zich ervan bewust zijn dat de ingestelde functie (max, min, tellen, enz.), Zodat ze de intentie van de codering kunnen begrijpen wanneer het is.

De ideale optimizer zal equivalente SQL-constructen herkennen en kiest altijd het ideale plan dienovereenkomstig. Voor uw echte SQL-motor van keuze, moet u testen:)

PS OPMERKING De positie van het verschillende sleutelwoord in de SELECT-clausule kan verschillende resultaten opleveren, b.v. CONTRAST:

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

18

Ik weet dat het een oude post is. Maar het gebeurt dat ik een query had die groep had gebruikt door alleen maar om verschillende waarden te retourneren bij het gebruik van die query in Pad en Oracle-rapporten Alles werkte alles, bedoel ik een goede responstijd. Toen we migreerden van Oracle 9i naar 11G was de responstijd in Pad was uitstekend, maar in de melding duurde het ongeveer 35 minuten om het rapport te voltooien bij het gebruik van vorige versie die het ongeveer 5 minuten duurde.

De oplossing was om de groep te wijzigen door te gebruiken en onderscheidend en nu loopt het rapport in ongeveer 30 seconden.

Ik hoop dat dit nuttig is voor iemand met dezelfde situatie.


19

U merkt alleen op dat u een enkele kolom selecteert.

Probeer twee velden te selecteren en zie wat er gebeurt.

Groep door is bedoeld om als volgt te worden gebruikt:

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

wat de som van alle transacties voor elke persoon zou tonen.


20

In termen van gebruik, groep door wordt gebruikt voor het groeperen van die rijen die u wilt berekenen. Verschillend zal geen berekening doen. Het toont geen dubbele rijen.

Ik heb altijd onderscheidend gebruikt als ik gegevens zonder duplicaten willen presenteren.

Als ik de berekeningen wil doen, zoals het samenvoegen van de totale hoeveelheid mango’s, gebruik ik groep met


21

De manier waarop ik altijd begreep, is dat het gebruik van verschillend is hetzelfde als groepering door elk veld dat u hebt geselecteerd in de volgorde die u ze hebt geselecteerd.

i.e:

select distinct a, b, c from table;

is hetzelfde als:

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

22

Functional-efficiëntie is totaal anders.
Als u alleen “retourwaarde” wilt selecteren, behalve Duplicate One, is gebruik onderscheidend is beter dan groep. Omdat “groep door” omvat (sorteren + verwijderen), “onderscheiden” omvat (verwijder)


23

Over het algemeen kunnen we DISTINCTgebruiken voor het elimineren van de duplicaten op specifieke kolom in de tabel.

In het geval van ‘groep door’ kunnen we de aggregatiefuncties toepassen zoals
AVG, MAX, MIN, SUM, EN COUNTOP SPECIFIEKE KOLOM EN FETCH
De kolomnaam en het IT-aggregatie-functie resulteert in dezelfde kolom.

Voorbeeld:

select  specialColumn,sum(specialColumn) from yourTableName group by specialColumn;

24

in bijenkorf (HQL), GROUP BYkan veel sneller zijn dan DISTINCT, omdat de eerste niet nodig is om alle velden in de tabel te vergelijken.

Zie: https: // sqlperformance .com / 2017/01 / T-SQL-Query’s / verrassingen-Assumptions-Group-By-Distince .


25

Er is geen significant verschil tussen groep door en verschillende clausule, behalve het gebruik van geaggregeerde functies.
Beide kunnen worden gebruikt om de waarden te onderscheiden, maar als in Performance Point of View Group Beter is.
Wanneer het verschillende sleutelwoord wordt gebruikt, gebruikte het intern de sorteerbewerking die in uitvoeringsplan kan worden bekeken.

Probeer eenvoudig voorbeeld

declareer @TMPresult-tabel
(
Id tinyint
)

Invoegen in @TMPresult
Selecteer 5
Unie allemaal
Selecteer 2
Unie allemaal
Selecteer 3
Unie allemaal
Selecteer 4

Selecteer Diffinict
ID kaart
Van @TMPresult

Other episodes