Uw zoekopdracht is volkomen legale syntaxis, u kunt sorteren op kolommen die niet aanwezig zijn in de selectie.
- Werkdemo met MySQL
- Werkdemo met SQL Server
- Werkdemo met Postgresql
- Werkdemo met SQLite
- Werkdemo met Oracle
Als u de volledige specificaties over juridische volgorde nodig hebt, heeft de SQL Standard 2003 een lange lijst met uitspraken over wat de volgorde door wel en niet zou moeten bevatten, (02-Foundation, pagina 415, sectie 7.13
Ik denk dat uw verwarring zou kunnen ontstaan door het selecteren en/of bestellen op kolommen die niet in de groep voorkomen op, of bestellen op kolommen die niet in de selectie staan wanneer u onderscheidend gebruikt.
Beiden hebben hetzelfde fundamentele probleem, en MySQL is de enige bij mijn weten die beide toelaat.
Het probleem is dat bij het gebruik van group by of distinct kolommen die niet in een van beide voorkomen, niet nodig zijn, dus het maakt niet uit of ze meerdere verschillende waarden in rijen hebben, omdat ze nooit nodig zijn. Stel je deze eenvoudige dataset voor:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
3 | B | Y |
Als je schrijft:
SELECT DISTINCT Column1
FROM T;
Je zou krijgen
Column1
---------
A
B
Als u vervolgens ORDER BY Column2
. toevoegt , welke van de twee kolom2's zou je gebruiken om A te ordenen op, X of Z? Het is niet bepalend voor het kiezen van een waarde voor kolom2.
Hetzelfde geldt voor het selecteren van kolommen die niet in de groep op staan. Om de zaken te vereenvoudigen, stelt u zich de eerste twee rijen van de vorige tabel eens voor:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
In MySQL kun je schrijven
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1;
Dit breekt eigenlijk de SQL-standaard, maar het werkt in MySQL, maar het probleem is dat het niet-deterministisch is, het resultaat:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
Is niet meer of minder correct dan
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
Dus wat je zegt is geef me een rij voor elke afzonderlijke waarde van Column1
, waaraan beide resultatenreeksen voldoen, dus hoe weet u welke u krijgt? Nou, dat doe je niet, het lijkt een vrij populaire misvatting te zijn die je kunt toevoegen en ORDER BY
clausule om de resultaten te beïnvloeden, dus bijvoorbeeld de volgende vraag:
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1
ORDER BY ID DESC;
Zou ervoor zorgen dat u het volgende resultaat krijgt:
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
vanwege de ORDER BY ID DESC
, maar dit is niet waar (zoals hier aangetoond
).
De MySQL-documenten staat:
Dus ook al heb je een bestelling, deze is pas van toepassing nadat één rij per groep is geselecteerd, en deze ene rij is niet bepalend.
De SQL-standaard staat wel kolommen toe in de selectielijst die niet in de GROUP BY of een aggregatiefunctie voorkomen, maar deze kolommen moeten functioneel afhankelijk zijn van een kolom in de GROUP BY. Van de SQL-2003-Standard (5WD-02-Foundation-2003-09 - pagina 346) - http ://www.wiscorp.com/sql_2003_standard.zip
ID in de voorbeeldtabel is bijvoorbeeld de PRIMARY KEY, dus we weten dat deze uniek is in de tabel, dus de volgende query voldoet aan de SQL-standaard en zou in MySQL worden uitgevoerd en momenteel in veel DBMS mislukken (op het moment van schrijven van Postgresql is het DBMS dat ik ken om de standaard correct te implementeren - Voorbeeld hier ):
SELECT ID, Column1, Column2
FROM T
GROUP BY ID;
Aangezien ID uniek is voor elke rij, kan er slechts één waarde zijn van Column1
voor elke ID, één waarde van Column2
er is geen onduidelijkheid over wat voor elke rij moet worden geretourneerd.