2009-03-04 10 views
19

Come posso essere sicuro che il mio set di risultati avrà prima a e b? Mi aiuterebbe a risolvere un problema di ordinazioni complicato.Come posso ordinare le voci in UNION senza ORDER BY?

Ecco un esempio semplificato di quello che sto facendo:

SELECT a FROM A LIMIT 1 
UNION 
SELECT b FROM B LIMIT 1; 
+1

@tharkun: Mi rendo conto che non ti piace RichB, ma renditi conto di come appare la tua domanda sulla pagina principale se le sole due righe che vedi sono codice SQL e non la domanda. Ecco perché l'ha modificato come ha fatto, e francamente, la sua modifica ha fatto sembrare la domanda molto meglio. –

+0

@tharkun: Separa il suo tono "aspro" dalle sue modifiche. Sono separati. Di sicuro è crudele nella sua lingua; ma questo non rende le sue modifiche meno valide. –

+0

Ripristinato alle modifiche di Rich. Non schierarsi con qualcuno o qualcosa di diverso dalla qualità della domanda. –

risposta

34
SELECT col 
FROM 
    (
     SELECT a col, 0 ordinal FROM A LIMIT 1 
     UNION ALL 
     SELECT b, 1 FROM B LIMIT 1 
    ) t 
ORDER BY ordinal 
+0

che sembra essere la versione pro + di quello che suggerisce Dana, grazie! – markus

+0

è quello, se non voglio l'ordinale nel set di risultati, giusto ?! – markus

+0

e cosa fa il solitario 't' nella linea 7? – markus

1

So per Oracle non v'è alcun modo per garantire che uscirà prima, senza un ordine. Il problema è che se lo provi, potrebbe uscire nell'ordine corretto anche per la maggior parte delle volte che lo esegui. Ma non appena ne fai affidamento in produzione, verrà fuori sbagliato.

2

No, l'ordine dei risultati in una query SQL è controllato solo dalla clausola ORDER BY. Potrebbe essere che ti capiti di vedere risultati ordinati senza una clausola ORDER BY in alcune situazioni, ma questo è un caso (ad esempio un effetto collaterale del piano di query corrente dell'ottimizzatore) e non è garantito.

Qual è il problema con gli ordini?

+0

grazie, ho pensato così ... il difficile problema di ordinamento, se rimarrà complicato sarà il contenuto di un'altra domanda che vorrei collegare qui . – markus

20

Non penso che l'ordine sia garantito, almeno non attraverso tutti i DBMS.

Quello che ho fatto in passato per controllare l'ordine in Unioni è:

(SELECT a, 0 AS Foo FROM A LIMIT 1) 
UNION 
(SELECT b, 1 AS Foo FROM B LIMIT 1) 
ORDER BY Foo 
+0

oh, è geniale, facile e geniale! – markus

+0

Sei sicuro che l'ordine di non verrà applicato solo all'ultima query nell'unione? –

+0

@Kjetil: in realtà hai ragione, ci devono essere parentesi – markus

0

avrei pensato non, dal momento che il database molto probabilmente bisogno di fare un ORDER BY per UNION .

UNION ALL potrebbe comportarsi in modo diverso, ma YMMV.

+0

UNION ALL garantisce semplicemente che tutti i record vengano restituiti. Una semplice UNION filtra i duplicati. – Dana

-6

La risposta è sì, si otterrà A allora B.

+0

e qual è la risposta lunga, dato che tutti altrimenti dice il contrario? – markus

+0

La risposta lunga sarebbe che senza una clausola ORDER BY, si otterrà FIFO in base alla clausola UNION. Ad esempio, la tabella B specificata per prima nell'UNION sarebbe yeild, B-> A. UNION non comporta alcun tipo di ordinamento in sé e per sé. – Bill

+0

ppl non sembrano essere d'accordo con te, puoi dimostrare il tuo reclamo? – markus

4

vostro set di risultati con UNION eliminerà valori distinti.

Non riesco a trovare alcuna prova nella documentazione, ma da 10 anni di esperienza posso dire che lo UNION ALL conserva l'ordine, almeno in Oracle.

Non contare su questo, tuttavia, se si sta costruendo una centrale nucleare o qualcosa del genere.

+3

sì, sto costruendo una centrale nucleare! ;) – markus

+0

Sembra funzionare. Ha senso che l'unione guasterà l'ordine se sta controllando i duplicati, mentre l'unione non lo farà – David