La tua query ha una sintassi perfettamente legale, puoi ordinare per colonne che non sono presenti nella selezione.
- Dimostrazione di lavoro con MySQL
- Dimostrazione di lavoro con SQL Server
- Dimostrazione di lavoro con Postgresql
- Dimostrazione di lavoro con SQLite
- Dimostrazione di lavoro con Oracle
Se hai bisogno delle specifiche complete sull'ordinamento legale, in SQL Standard 2003 ha un lungo elenco di istruzioni su ciò che l'ordine dovrebbe e non dovrebbe contenere, (02-Foundation, pagina 415, sezione 7.13
Penso che la tua confusione potrebbe derivare dalla selezione e/o dall'ordinamento per colonne non presenti nel raggruppamento o dall'ordinamento per colonne non presenti nella selezione quando si utilizza distinto.
Entrambi hanno lo stesso problema fondamentale e MySQL è l'unico a mia conoscenza che consente entrambi.
Il problema è che quando si utilizza il raggruppamento per o il distinto, le colonne non contenute in nessuna delle due non sono necessarie, quindi non importa se hanno più valori diversi tra le righe perché non sono mai necessarie. Immagina questo semplice set di dati:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
3 | B | Y |
Se scrivi:
SELECT DISTINCT Column1
FROM T;
Avresti
Column1
---------
A
B
Se poi aggiungi ORDER BY Column2
, quale delle due colonne 2 useresti per ordinare A per, X o Z? Non è deterministico come scegliere un valore per column2.
Lo stesso vale per la selezione di colonne non nel raggruppamento per. Per semplificare, immagina le prime due righe della tabella precedente:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
In MySQL puoi scrivere
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1;
Questo in realtà infrange lo standard SQL, ma funziona in MySQL, tuttavia il problema è che non è deterministico, il risultato:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
Non è più o meno corretto di
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
Quindi quello che stai dicendo è dammi una riga per ogni valore distinto di Column1
, che soddisfano entrambi i set di risultati, quindi come fai a sapere quale otterrai? Beh, non lo fai, sembra essere un malinteso abbastanza popolare che puoi aggiungere e ORDER BY
clausola per influenzare i risultati, quindi ad esempio la seguente query:
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1
ORDER BY ID DESC;
Ti assicurerei di ottenere il seguente risultato:
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
a causa del ORDER BY ID DESC
, tuttavia questo non è vero (come dimostrato qui
).
I documenti MySQL stato:
Quindi, anche se hai un ordine, questo non si applica fino a quando non è stata selezionata una riga per gruppo e questa riga non è deteristica.
Lo standard SQL non consente colonne nell'elenco di selezione non contenute in GROUP BY o in una funzione di aggregazione, tuttavia queste colonne devono dipendere funzionalmente da una colonna in GROUP BY. Dallo standard SQL-2003 (5WD-02-Foundation-2003-09 - pagina 346) - http ://www.wiscorp.com/sql_2003_standard.zip
Ad esempio, l'ID nella tabella di esempio è la CHIAVE PRIMARIA, quindi sappiamo che è univoca nella tabella, quindi la query seguente è conforme allo standard SQL e verrebbe eseguita in MySQL e attualmente non riuscirebbe in molti DBMS (Al momento della scrittura di Postgresql è il DBMS più vicino che conosco per implementare correttamente lo standard - Esempio qui ):
SELECT ID, Column1, Column2
FROM T
GROUP BY ID;
Poiché l'ID è univoco per ogni riga, può esserci un solo valore di Column1
per ogni ID, un valore di Column2
non ci sono ambiguità su cosa restituire per ogni riga.