Mysql
 sql >> Database >  >> RDS >> Mysql

Quali DBMS consentono un ordine per un attributo, che non è presente nella clausola select?

La tua query ha una sintassi perfettamente legale, puoi ordinare per colonne che non sono presenti nella selezione.

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 , sub parte 28). Ciò conferma che la tua query è una sintassi legale.

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.