SQL Query – Usando Order By in UNION

Come si può ordinare a livello di codice una query di unione quando si estraggono i dati da due tabelle? Per esempio,

SELECT table1.field1 FROM table1 ORDER BY table1.field1 UNION SELECT table2.field1 FROM table2 ORDER BY table2.field1 

Genera un’eccezione

Nota: questo viene tentato sul motore di database MS Access Jet

A volte è necessario avere l’ ORDER BY in ciascuna delle sezioni che devono essere combinate con UNION .

In questo caso

 SELECT * FROM ( SELECT table1.field1 FROM table1 ORDER BY table1.field1 ) DUMMY_ALIAS1 UNION ALL SELECT * FROM ( SELECT table2.field1 FROM table2 ORDER BY table2.field1 ) DUMMY_ALIAS2 
 SELECT field1 FROM table1 UNION SELECT field1 FROM table2 ORDER BY field1 

Penso che questo faccia un buon lavoro di spiegazione.

Quella che segue è una query UNION che utilizza una clausola ORDER BY:

 select supplier_id, supplier_name from suppliers where supplier_id > 2000 UNION select company_id, company_name from companies where company_id > 1000 ORDER BY 2; 

Poiché i nomi delle colonne sono diversi tra le due istruzioni “select”, è più vantaggioso fare riferimento alle colonne nella clausola ORDER BY in base alla loro posizione nel set di risultati.

In questo esempio, abbiamo ordinato i risultati per supplier_name / company_name in ordine crescente, come indicato da “ORDER BY 2”.

I campi supplier_name / company_name sono nella posizione n. 2 del set di risultati.

Tratto da qui: http://www.techonthenet.com/sql/union.php

Usando un esempio concreto:

 SELECT name FROM Folders ORDER BY name UNION SELECT name FROM Files ORDER BY name 

File:

 name ============================= RTS.exe thiny1.etl thing2.elt f.txt tcpdump_trial_license (1).zip 

Cartelle:

 name ============================ Contacts Desktop Downloads Links Favorites My Documents 

Output desiderato: (risultati della prima selezione prima, cioè prima le cartelle)

 Contacts Desktop Downloads Favorites Links My Documents f.txt RTMS.exe tcpdump_trial_license (1).zip thiny1.etl thing2.elt 

SQL per ottenere i risultati desiderati:

 SELECT name FROM ( SELECT 1 AS rank, name FROM Folders UNION SELECT 2 AS rank, name FROM Files) dt ORDER BY rank, name 

Ecco un esempio di Northwind 2007:

 SELECT [Product ID], [Order Date], [Company Name], [Transaction], [Quantity] FROM [Product Orders] UNION SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] FROM [Product Purchases] ORDER BY [Order Date] DESC; 

La clausola ORDER BY ha solo bisogno di essere l’ultima dichiarazione, dopo che hai fatto tutto il tuo sindacato. È ansible unire più insiemi, quindi inserire una clausola ORDER BY dopo l’ultimo set.

 (SELECT table1.field1 FROM table1 UNION SELECT table2.field1 FROM table2) ORDER BY field1 

Lavoro? Ricorda set di pensieri. Prendi il set che desideri usando un sindacato e poi esegui le tue operazioni su di esso.

 SELECT table1Column1 as col1,table1Column2 as col2 FROM table1 UNION ( SELECT table2Column1 as col1, table1Column2 as col2 FROM table2 ) ORDER BY col1 ASC 
 SELECT field1 FROM ( SELECT field1 FROM table1 UNION SELECT field1 FROM table2 ) AS TBL ORDER BY TBL.field1 

(usa ALIAS)

Questa è la cosa più stupida che abbia mai visto, ma funziona, e non puoi discutere con i risultati.

 SELECT * FROM ( SELECT table1.field1 FROM table1 ORDER BY table1.field1 UNION SELECT table2.field1 FROM table2 ORDER BY table2.field1 ) derivedTable 

L’interno della tabella derivata non verrà eseguito da solo, ma come una tabella derivata funziona perfettamente. Ho provato questo su SS 2000, SS 2005, SS 2008 R2 e tutti e tre funzionano.

Questo è come è fatto

 select * from (select top 100 percent pointx, pointy from point where pointtype = 1 order by pointy) A union all select * from (select top 100 percent pointx, pointy from point where pointtype = 2 order by pointy desc) B 

Navigando in questa sezione di commenti sono arrivato attraverso due diversi modelli che rispondono alla domanda. Purtroppo per SQL 2012, il secondo pattern non funziona, quindi ecco il mio “work around”


Ordina per una colonna comune

Questo è il caso più facile che puoi incontrare. Come molti utenti hanno sottolineato, tutto ciò che devi veramente fare è aggiungere un Order By alla fine della query

 SELECT a FROM table1 UNION SELECT a FROM table2 ORDER BY field1 

o

 SELECT a FROM table1 ORDER BY field1 UNION SELECT a FROM table2 ORDER BY field1 

Ordina per colonne diverse

Ecco dove in realtà diventa complicato. Utilizzando SQL 2012, ho provato il post principale e non funziona.

 SELECT * FROM ( SELECT table1.field1 FROM table1 ORDER BY table1.field1 ) DUMMY_ALIAS1 UNION ALL SELECT * FROM ( SELECT table2.field1 FROM table2 ORDER BY table2.field1 ) DUMMY_ALIAS2 

Seguendo la raccomandazione nel commento ho provato questo

 SELECT * FROM ( SELECT TOP 100 PERCENT table1.field1 FROM table1 ORDER BY table1.field1 ) DUMMY_ALIAS1 UNION ALL SELECT * FROM ( SELECT TOP 100 PERCENT table2.field1 FROM table2 ORDER BY table2.field1 ) DUMMY_ALIAS2 

Questo codice è stato compilato ma DUMMY_ALIAS1 e DUMMY_ALIAS2 sovrascrivono l’ Order By in base all’istruzione Select che lo rende inutilizzabile.

L’unica soluzione a cui potevo pensare, che funzionava per me, non era l’utilizzo di un sindacato e invece le query venivano eseguite singolarmente e poi gestite con esse. Quindi, in pratica, non usare Union quando si desidera Order By

Usando l’ordine separatamente, ogni sottoinsieme ottiene l’ordine, ma non l’intero insieme, che è ciò che si vorrebbe unire due tabelle.

Dovresti usare qualcosa come questo per avere un set ordinato:

 SELECT TOP (100) PERCENT field1, field2, field3, field4, field5 FROM (SELECT table1.field1, table1.field2, table1.field3, table1.field4, table1.field5 FROM table1 UNION ALL SELECT table2.field1, table2.field2, table2.field3, table2.field4, table2.field5 FROM table2) AS unitedTables ORDER BY field5 DESC 

La seconda tabella non può includere il nome della tabella nella clausola ORDER BY .

Così…

 SELECT table1.field1 FROM table1 ORDER BY table1.field1 UNION SELECT table2.field1 FROM table2 ORDER BY field1 

Non getta un’eccezione

Se necessario, mantenere lo smistamento interno:

 SELECT 1 as type, field1 FROM table1 UNION SELECT 2 as type, field1 FROM table2 ORDER BY type, field1 
 (SELECT FIELD1 AS NEWFIELD FROM TABLE1 ORDER BY FIELD1) UNION (SELECT FIELD2 FROM TABLE2 ORDER BY FIELD2) UNION (SELECT FIELD3 FROM TABLE3 ORDER BY FIELD3) ORDER BY NEWFIELD 

Prova questo. Ha funzionato per me.

Per Sql Server 2014/2012 / Altri (non selezionato):

 SELECT * FROM ( SELECT table1.field1 FROM table1 ORDER BY table1.field1 ) as DUMMY_ALIAS1 UNION ALL SELECT * FROM ( SELECT table2.field1 FROM table2 ORDER BY table2.field1 ) as DUMMY_ALIAS2