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:

  1. Wat is de betekenis van het gebruik van GROUP BY zonder enige aggregatie uit te voeren?
  2. Wat is de betekenis van het veranderen van de volgorde van kolommen in SELECT versus in GROUP BY ?
  3. Wat is de betekenis van het weglaten van de derde kolom van GROUP BY?
  4. Waarom is DISTINCT gebruikt in combinatie met GROUP BY? Wordt een aparte bewerking uitgevoerd nadat alle groeperingen op het eindresultaat of daarvoor zijn uitgevoerd?

Opmerkingen

  • Item 2: Er is geen betekenis. De GROUP BY doet er helemaal niet toe (behalve dat het in oude versies hetzelfde impliceerde ORDER BY. De SELECT volgorde is alleen van belang bij de rangschikking van kolommen in de uitvoer.

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *