Ik zag de volgende MySQL-query die zowel DISTINCT als GROUP BY samen gebruikt:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
Hier is een scenario dat bij de zoekopdracht past: elke gebruiker heeft een unieke id, user_id
, en kan meerdere berichten plaatsen die worden geïdentificeerd door een unieke id, post_id
. Elk bericht zou wat tekst bevatten.
Ik vond dit verwarrend (nadat ik uit Oracle DBs kwam) en had onderstaande vragen:
- Wat is de betekenis van het gebruik van
GROUP BY
zonder enige aggregatie uit te voeren? - Wat is de betekenis van het veranderen van de volgorde van kolommen in
SELECT
versus inGROUP BY
? - Wat is de betekenis van het weglaten van de derde kolom van
GROUP BY
? - Waarom is
DISTINCT
gebruikt in combinatie metGROUP BY
? Wordt een aparte bewerking uitgevoerd nadat alle groeperingen op het eindresultaat of daarvoor zijn uitgevoerd?
Opmerkingen
Antwoord
advertentie 1) Oude mysql-databases en als je ONLY_FULL_GROUP_BY uitschakelt, kun je deze vraag stellen en als de post_content allemaal gelijk zijn, zou je opmerken dat mysql een willekeurige niet-deterministische waarde teruggeeft .
advertentie 2) geen enkele
advertentie 3) lui programmeren en er treedt een fout op wanneer je ONLY_FULL_GROUP_BY
advertentie 4) Nee, het zou alle post_content weergeven die zijn verbonden met user_id, post_id vergelijkbaar met post_content aan de groep toevoegen door
Zoals Strawberry al zei, doet deze vraag het niet logisch
Antwoord
De waanzinnige mogelijkheid om een gedeeltelijke groep toe te staan in oudere versies van MyS QL, moet een van de grootste kanshebbers zijn voor de meest veroorzaakte verwarring in de it-industrie.
Gegeven de tabel:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
De verklaring
SELECT x, y FROM t GROUP BY x
zou kunnen betekenen (1,1) of (1,2) en MySQL zou willekeurig een van deze teruggeven. DISTINCT doet er in dit geval niet toe, het resultaat is nog steeds niet-deterministisch.
SQL92 vereiste dat alle kolommen in de select-clausule (behalve geaggregeerde kolommen en constanten) deel uitmaken van de GROUP BY-clausule.
SQL99 maakte deze beperking een beetje losser en stelde ons in staat kolommen weg te laten uit de GROUP BY die functioneel afhankelijk zijn van de overige kolommen. D.w.z.
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
zou geldig zijn aangezien y f.d. of x
Verrassend genoeg (voor mij) is een latere versie van MySQL de beste in zijn soort als het gaat om het implementeren van de SQL99-versie. Ik heb het de laatste tijd niet gecontroleerd, maar toen ik het deed, behandelde MySQL redelijk gecompliceerde scenarios goed, terwijl PostgreSQL alleen triviale scenarios behandelde.
Om je vragen te beantwoorden
1)
SELECT x, y FROM t GROUP BY x, y
betekent dat de combinatie van x, y een groep is. In alle mogelijke situaties is dit hetzelfde als:
SELECT DISTINCT x, y FROM t
Aangezien ze op verschillende tijdstippen logisch worden geëvalueerd, kan er een hoekgeval zijn waarin ze in feite verschillen (ik kan er echter geen bedenken)
2) Geen , in dit opzicht zijn het een reeks kolommen, dus er is geen volgorde
3) Zie hierboven.
4) De logische volgorde van evaluatie van een SQL-query is:
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
dus GROUP BY wordt verondersteld te worden geëvalueerd vóór DISTINCT. Ik kan geen situatie bedenken waarin dit ertoe doet.
In uw vraag Ik vermoed dat iemand verwarrende resultaten heeft gekregen en heeft geprobeerd een ander resultaat te krijgen met DISTINCT. Ze hadden waarschijnlijk geluk (of pech) om het resultaat te krijgen dat ze verwacht, dus de DISTINCT bleef. De bug is er echter nog steeds
GROUP BY
doet er helemaal niet toe (behalve dat het in oude versies hetzelfde impliceerdeORDER BY
. DeSELECT
volgorde is alleen van belang bij de rangschikking van kolommen in de uitvoer.