Din forespørgsel er fuldkommen lovlig syntaks, du kan sortere efter kolonner, der ikke er til stede i valget.
- Arbejdsdemo med MySQL
- Arbejdsdemo med SQL Server
- Arbejdsdemo med Postgresql
- Arbejdsdemo med SQLite
- Arbejdsdemo med Oracle
Hvis du har brug for de fulde specifikationer om juridisk bestilling, har den i SQL Standard 2003 en lang liste af udsagn om, hvad rækkefølgen af bør og ikke bør indeholde, (02-Foundation, side 415, afsnit 7.13
Jeg tror, at din forvirring kan opstå ved at vælge og/eller sortere efter kolonner, der ikke er til stede i gruppen, eller sortere efter kolonner, der ikke er i udvalg, når du bruger distinkt.
Begge har det samme grundlæggende problem, og MySQL er den eneste, så vidt jeg ved, der tillader enten.
Problemet er dette, at når du bruger gruppe efter eller adskilt, er der ikke behov for kolonner, der ikke er indeholdt i nogen af dem, så det er ligegyldigt, om de har flere forskellige værdier på tværs af rækker, fordi de aldrig er nødvendige. Forestil dig dette simple datasæt:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
3 | B | Y |
Hvis du skriver:
SELECT DISTINCT Column1
FROM T;
Du ville få
Column1
---------
A
B
Hvis du derefter tilføjer ORDER BY Column2
, hvilken af de to kolonne2'er ville du bruge til at bestille A efter, X eller Z? Det er ikke deterministisk, hvordan man vælger en værdi for kolonne 2.
Det samme gælder for valg af kolonner, der ikke er i gruppen efter. For at forenkle tingene skal du bare forestille dig de to første rækker i den foregående tabel:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
I MySQL kan du skrive
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1;
Dette bryder faktisk SQL-standarden, men det virker i MySQL, men problemet er, at det er ikke-deterministisk, resultatet:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
Er hverken mere eller mindre korrekt end
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
Så det, du siger, er giv mig en række for hver særskilt værdi af Column1
, som begge resultatsæt opfylder, så hvordan ved du, hvilken du får? Nå det gør du ikke, det ser ud til at være en ret populær misforståelse, at du kan tilføje og ORDER BY
klausul for at påvirke resultaterne, så for eksempel følgende forespørgsel:
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1
ORDER BY ID DESC;
Ville sikre, at du får følgende resultat:
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
på grund af ORDER BY ID DESC
, men dette er ikke sandt (som vist her
).
MySQL-dokumenterne angiv:
Så selvom du har en ordre, gælder dette ikke før efter en række pr. gruppe er valgt, og denne ene række er ikke-deterministisk.
SQL-standarden tillader kolonner i valglisten, der ikke er indeholdt i GROUP BY eller en aggregeret funktion, men disse kolonner skal være funktionelt afhængige af en kolonne i GROUP BY. Fra SQL-2003-Standard (5WD-02-Foundation-2003-09 - side 346) - http ://www.wiscorp.com/sql_2003_standard.zip
For eksempel er ID i eksempeltabellen den PRIMÆRE NØGLE, så vi ved, at den er unik i tabellen, så den følgende forespørgsel er i overensstemmelse med SQL-standarden og ville køre i MySQL og fejle i mange DBMS i øjeblikket (På skrivende stund Postgresql er det nærmeste DBMS, jeg kender til korrekt implementering af standarden - Eksempel her ):
SELECT ID, Column1, Column2
FROM T
GROUP BY ID;
Da ID er unikt for hver række, kan der kun være én værdi af Column1
for hvert id, én værdi af Column2
der er ingen uklarhed om, hvad der skal returneres for hver række.