2010-08-20 17 views
85

Voglio utilizzare l'ordine con union nella query mysql. Sto recuperando diversi tipi di record in base a criteri diversi da una tabella in base alla distanza per una ricerca sul mio sito. La prima query di selezione restituisce i dati relativi alla ricerca esatta del luogo. La seconda query di selezione restituisce i dati relativi alla distanza entro 5 km dal luogo cercato. La terza query di selezione restituisce i dati relativi alla distanza entro 5-15 km dal luogo cercato.Utilizzo unione e ordine per clausola in mysql

Quindi utilizzo union per unire tutti i risultati e mostrare su una pagina con paging. Sotto l'intestazione appropriata come 'dei risultati delle ricerche esatti', 'Risultati entro 5 km' ecc

Ora voglio ordinare i risultati in base all'ID o add_date. Ma quando aggiungo ordine per clausola alla fine della mia query (query1 unione query 2 unione query 3 ordine da add_date). Ordina tutti i risultati. Ma quello che voglio è che dovrebbe essere ordinato sotto ogni voce.

+0

Che tipo/i è/sono il/i campo/i che si desidera ordinare in ciascuna tabella? – user151841

risposta

163

si può fare questo con l'aggiunta di un rango pseudo-colonna denominata ad ogni selezionata, che è possibile ordinare per prima, prima che l'ordinamento per gli altri criteri, ad esempio:

select * 
from (
    select 1 as Rank, id, add_date from Table 
    union all 
    select 2 as Rank, id, add_date from Table where distance < 5 
    union all 
    select 3 as Rank, id, add_date from Table where distance between 5 and 15 
) a 
order by rank, id, add_date desc 
+0

Ciao, grazie per quello, sto esattamente usando in questo modo. Ma quello che voglio è che voglio ordinare selezionare il risultato della query basato su add_date in ordine decrescente. – Aditya

+0

È possibile utilizzare la parola chiave 'desc' per questo. Ho aggiornato la query sopra. – RedFilter

+0

Ho appena fatto un rapido cambio di codici, ed i risultati sono stati fantastici. Hai reso la mia giornata. Grazie – Aditya

0

Prova:

SELECT result.* 
FROM (
[QUERY 1] 
UNION 
[QUERY 2] 
) result 
ORDER BY result.id 

Dove [Query 1] e [Query 2] sono i tuoi due query che si desidera unire.

0

Questo è perché sei l'ordinamento intero risultato-set, si dovrebbe ordinare, ogni parte di unione separatamente, oppure è possibile utilizzare ORDER BY (Qualcosa cioè. Sottoquery distanza) THEN (qualcosa cioè fila id) Clausola

4

una query di unione può avere un solo padrone ORDER BY clausola , IIRC. Per ottenere ciò, in ogni query che compone la query maggiore UNION, aggiungere un campo che sarà il campo che si ordina in base allo ORDER BYUNION.

Per esempio, si potrebbe avere qualcosa di simile

SELECT field1, field2, '1' AS union_sort 
UNION SELECT field1, field2, '2' AS union_sort 
UNION SELECT field1, field2, '3' AS union_sort 
ORDER BY union_sort 

Che union_sort campo può essere qualsiasi cosa, si consiglia di ordinare. In questo esempio, accade solo mettere i risultati dalla prima tabella prima, seconda tabella secondo, ecc

38

È possibile utilizzare sottoquery per effettuare questa operazione:

select * from (select values1 from table1 order by orderby1) as a 
union all 
select * from (select values2 from table2 order by orderby2) as b 
+1

Tnx, buono per separare gli ordini. Possiamo anche avere un accordo diverso se la clausola dell'ordine fosse comune ma vogliamo che i risultati siano separati (invece di separare gli ordini): 'SELECT * FROM ( SELECT aaa AS Col, 1 AS Official DA tabella1 UNION ALL SELECT bbb AS Col, 0 AS Official FROM table2 ) AS tbl ORDER BY Official, Col' – Alix

+6

Questo è [errato] (http://dev.mysql.com/doc/refman/5.7/en/union.html): * l'uso di 'ORDER BY' per le singole istruzioni' SELECT' non implica nulla sull'ordine in cui appaiono le righe nel risultato finale * – shmosel

+0

Hai ragione, la risposta accettata è anche quella corretta. Questo è appena successo per funzionare bene quando l'ho testato. – rickythefox

0

Ho provato ad aggiungere l'ordine a ciascuna le domande prima del sindacato come

(select * from table where distance=0 order by add_date) 
union 
(select * from table where distance>0 and distance<=5 order by add_date) 

ma non sembra funzionare. In realtà non ha fatto l'ordine all'interno delle righe da ciascuna selezione.

penso che sarà necessario mantenere l'ordine sul lato esterno e aggiungere le colonne nella clausola in cui l'ordine da parte, qualcosa come

(select * from table where distance=0) 
union 
(select * from table where distance>0 and distance<=5) 
order by distance, add_date 

Questo può essere un po 'difficile, dal momento che si desidera raggruppa per intervalli, ma penso che dovrebbe essere fattibile.

+0

user151841 union_sort l'idea di seguito sarebbe un buon modo per gestire il raggruppamento –

2

Ho ottenuto questo lavoro su un join più unione.

(SELECT 
    table1.column1, 
    table1.column2, 
    foo1.column4 
FROM table1, table2, foo1, table5 
WHERE table5.somerecord = table1.column1 
ORDER BY table1.column1 ASC, table1.column2 DESC 
) 

UNION 

(SELECT 
    ... Another complex query as above 
) 

ORDER BY column1 DESC, column2 ASC 
23
(select add_date,col2 from table_name) 
    union 
(select add_date,col2 from table_name) 
    union 
(select add_date,col2 from table_name) 

order by add_date 
+0

Questo ha funzionato, ma stranamente ho dovuto cambiare una cosa: avevo bisogno di dare un alias condiviso al campo che stava ordinando. Oltre a ciò, grazie! – HoldOffHunger

6

Non dimenticate, l'unione tutto è un modo per aggiungere record a un set di record, senza ordinamento o la fusione (al contrario di unione).

Così, per esempio:

select * from (
    select col1, col2 
    from table a 
    <....> 
    order by col3 
    limit by 200 
) a 
union all 
select * from (
    select cola, colb 
    from table b 
    <....> 
    order by colb 
    limit by 300 
) b 

Mantiene le singole query più chiaro e consente di ordinare da diversi parametri in ogni query. Tuttavia, utilizzando la modalità di risposta selezionata, potrebbe risultare più chiara in base alla complessità e al modo in cui i dati sono correlati, in quanto si sta concettualizzando l'ordinamento. Consente inoltre di restituire la colonna artificiale al programma di query in modo che abbia un contesto che può ordinare o organizzare.

Ma in questo modo ha il vantaggio di essere veloce, non introduce variabili aggiuntive e rende semplice separare ogni query incluso l'ordinamento. La possibilità di aggiungere un limite è semplicemente un bonus extra.

E ovviamente sentitevi liberi di trasformare il sindacato in unione e aggiungere un ordinamento per l'intera query. Oppure aggiungi un ID artificiale, nel qual caso in questo modo è facile ordinare i diversi parametri in ogni query, ma altrimenti è uguale alla risposta accettata.