2013-04-02 13 views
34

Posso essere sicuro che il set di risultati del seguente script sarà sempre ordinato come questo O-R-D-E-R?UNION ALL garantisce l'ordine del set di risultati

SELECT 'O' 
UNION ALL 
SELECT 'R' 
UNION ALL 
SELECT 'D' 
UNION ALL 
SELECT 'E' 
UNION ALL 
SELECT 'R' 

Può essere provato a volte essere in un ordine diverso?

+8

Perché qualcuno dovrebbe offrire una garanzia di ordinazione tranne quando è inclusa una clausola 'ORDER BY'? - Esiste un'opportunità ovvia per il parallelismo (se sono disponibili risorse sufficienti) per calcolare ogni set di risultati in parallelo e servire ogni riga del risultato (dalle query parallele) al client in qualsiasi ordine che ogni singola riga di risultati diventa disponibile. –

+2

@Damien_The_Unbeliever e ognuno può essere ottimizzato per ordinare in modo diverso a causa di altri fattori non ovvi nella query stessa. –

+0

@Damien_The_Unbeliever. . . Infatti, MySQL garantisce l'ordine dopo un 'group by' (" Se usi GROUP BY, le righe di output sono ordinate in base alle colonne GROUP BY come se avessi un ORDER BY per le stesse colonne. "A http: // dev.mysql.com/doc/refman/5.5/en/select.html). Considero questo un grosso limite alla capacità di MySQL di ottimizzare le espressioni di aggregazione. Non supporta nemmeno le aggregazioni di hash. –

risposta

44

Non c'è un ordine intrinseco, è necessario utilizzare ORDER BY. Per il tuo esempio puoi farlo facilmente aggiungendo uno SortOrder a ciascuna SELECT. Questo sarà quindi tenere i registri nell'ordine desiderato:

SELECT 'O', 1 SortOrder 
UNION ALL 
SELECT 'R', 2 
UNION ALL 
SELECT 'D', 3 
UNION ALL 
SELECT 'E', 4 
UNION ALL 
SELECT 'R', 5 
ORDER BY SortOrder 

Non è possibile garantire l'ordine a meno che non si fornisce specificatamente un ordine con la query.

+0

+1 Risposta migliore prima della modifica di Gordon. – Kermit

+2

Ho sentito un sacco di persone che dicono che non sarà sempre nello stesso ordine, e una documentazione variegata, ma nessuna prova empirica: mi piacerebbe essere in grado di eseguire una query e vederla effettivamente sputare i risultati in un ordine diverso. – whytheq

+6

@whytheq non vedere un orso nei boschi durante un'escursione non significa che non ci sono orsi nei boschi. Anche se l'ordine * potrebbe * essere garantito, cosa diavolo ottieni da questo? Non è necessario digitare "ORDER BY" in questo caso specifico? Ciò ti farà risparmiare un sacco di produttività oltre a essere esplicito.

37

No, non è così. Le tabelle SQL sono intrinsecamente non ordinate. È necessario utilizzare order by per ottenere le cose nell'ordine desiderato.

Il problema non è se funziona una volta quando lo provi. Il problema è se è possibile fidarsi di questo comportamento. E tu non puoi SQL Server non garantisce nemmeno l'ordine per questo:

select * 
from (select t.* 
     from t 
     order by col1 
    ) t 

Si dice here:

Quando ORDER BY viene utilizzata nella definizione di una visione, funzione inline, tabella derivata, o subquery, la clausola viene utilizzata solo per determinare le righe restituite dalla clausola TOP. La clausola ORDER BY non garantisce risultati ordinati quando questi costrutti vengono interrogati, a meno che ORDER BY sia specificato anche nella query stessa.

Un principio fondamentale del linguaggio SQL è che le tabelle non sono ordinate. Pertanto, sebbene la query possa funzionare in molti database, è necessario utilizzare la versione suggerita da BlueFeet per garantire l'ordine dei risultati.

+1

Quante volte lo eseguiamo su chi ha mai la macchina sembra ancora scrivere "ORDINE"! ... possiamo provare che a volte sarà in un ordine diverso? – whytheq

+4

Non pensare in termini di macchine discrete. Pensa in termini di set. Devi necessariamente ESEGUIRE l'ordine del set se ne hai bisogno, altrimenti è semplicemente un sacco di righe. – Tim

+5

@whytheq - può sembrare lo stesso, ma a volte la 2a lettera e la 5a posizione di cambio. –

5

No. Ottieni i record in qualsiasi modo in cui SQL Server li preleva per te. È possibile applicare un ordine su un risultato unioned fissato dal indice 1 a base di questa convenzione:

SELECT 1, 'O' 
UNION ALL 
SELECT 2, 'R' 
UNION ALL 
SELECT 3, 'D' 
UNION ALL 
SELECT 4, 'E' 
UNION ALL 
SELECT 5, 'R' 
ORDER BY 1 
+3

ORDINE è scritto "sbagliato" ora perché l'ordine è in ordine alfabetico. Se aggiungi un indice numerico puoi forzare l'ortografia "corretta". Vedi la modifica sopra. –

+6

Dovresti applicare un alias di colonna alla prima colonna e ordinare per quello. [Ordinare per posizione ordinale è una cattiva abitudine] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/06/bad-habits-to-kick-order-by-ordinal.aspx) che funziona bene qui ma potrebbe rompere altrove. –

+0

L'ordinamento per posizione ordinale è molto conveniente per lo sviluppo rapido, ma non è supportato in Oracle, ad esempio. –

16

Provare a rimuovere tutti i ALL s, ad esempio. O anche solo uno di loro. Considerate ora che il tipo di ottimizzazione che deve verificarsi lì (e molti altri tipi) sarà anche possibile quando le query SELECT sono query effettive rispetto alle tabelle e sono ottimizzate separatamente. Senza uno ORDER BY, l'ordine all'interno di ogni query sarà arbitrario e non è possibile garantire che le query stesse verranno elaborate in qualsiasi ordine.

Dire UNION ALL con il numero ORDER BY è come dire "Basta lanciare tutte le biglie sul pavimento". Forse ogni volta che lanci tutte le biglie sul pavimento, finiscono per essere organizzate per colore. Ciò non significa che la prossima volta che li getti sul pavimento si comporteranno allo stesso modo. Lo stesso vale per gli ordini in SQL Server - se non si dice ORDER BY allora SQL Server presume che non si preoccupi per l'ordine. È possibile visualizzare per coincidenza un determinato ordine che viene sempre restituito, ma molte cose possono influenzare l'ordine arbitrario selezionato successivo allo. Cambiamenti di dati, modifiche delle statistiche, ricompilazione, plan flush, upgrade, service pack, hotfix, flag di traccia ... fino alla nausea.

farò mettere questo a grandi lettere per mettere in chiaro:

Non si può garantire un ordine senza ORDER BY

Qualche ulteriore lettura:

http://sqlblog.com/blogs/aaron_bertrand/archive/2010/02/08/bad-habits-to-kick-relying-on-undocumented-behavior.aspx

Inoltre, please read this post by Conor Cunningham, a pretty smart guy on the SQL team.

+2

Riesci a rendere quel carattere un po 'più grande che non capisco? :) – Taryn

+3

@bluefeet solo se collegato a un SQLfiddle. :-) –

+0

Posso aggiungerlo per te se vuoi. – Taryn

Problemi correlati