Domanda

Come si può ordinare a livello di codice una query di unione quando si estraggono dati da due tabelle? Ad 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 è stato tentato sul motore di database di MS Access Jet

È stato utile?

Soluzione

A volte devi avere 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

Altri suggerimenti

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

Penso che questo faccia un buon lavoro di spiegazione.

Di seguito è riportata 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 i due " seleziona " istruzioni, è 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 nome_mittente / nome_azienda in ordine crescente, come indicato da " ORDER BY 2 " ;.

I campi supplier_name / company_name sono nella posizione # 2 nella 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, ovvero prima delle 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 deve essere solo l'ultima affermazione, dopo aver eseguito tutte le operazioni di unione. Puoi unire più set, quindi inserire una clausola ORDER BY dopo l'ultimo set.

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

Il lavoro? Ricorda pensa insiemi. Ottieni il set che desideri utilizzando un sindacato e quindi esegui le 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 poiché una tabella derivata funziona perfettamente. Ho provato questo su SS 2000, SS 2005, SS 2008 R2 e tutti e tre i lavori.

Ecco come viene 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

Sfogliando questa sezione di commento sono arrivato attraverso due diversi schemi di risposta alla domanda. Purtroppo per SQL 2012, il secondo modello non funziona, quindi ecco il mio " aggirare "


Ordina per su una colonna comune

Questo è il caso più semplice che puoi incontrare. Come molti utenti hanno sottolineato, tutto ciò che devi fare è aggiungere un Ordina per 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 su colonne diverse

Ecco dove diventa effettivamente difficile. Usando SQL 2012, ho provato il primo post 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 hanno la precedenza sul Ordina per stabilito nell'istruzione Select che rende questo inutilizzabile.

L'unica soluzione che mi è venuta in mente, che ha funzionato per me, è stata quella di non utilizzare un sindacato e invece di far funzionare le query singolarmente e quindi gestirle. Quindi, fondamentalmente, non utilizzare un Union quando si desidera Ordina per

Usando l'ordine separatamente ogni sottoinsieme ottiene l'ordine, ma non l'intero set, che è ciò che vorresti unire due tabelle.

Dovresti usare qualcosa del genere per avere uno 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 .

...

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

Non genera un'eccezione

Se necessario per mantenere l'ordinamento 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 verificato):

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top