web-dev-qa-db-fra.com

Requête SQL - Utilisation de Order By dans UNION

Comment peut-on trier par programme une requête d'union lors de l'extraction de données de deux tables? Par exemple,

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

Lance une exception

Remarque: cela est tenté sur le moteur de base de données MS Access Jet.

83

Parfois, vous devez avoir le ORDER BY dans chacune des sections devant être combinées avec UNION.

Dans ce cas

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
117
ajgreyling
SELECT field1 FROM table1
UNION
SELECT field1 FROM table2
ORDER BY field1
64
Anne Porosoff

Je pense que cela explique très bien.

Voici une requête UNION qui utilise une clause 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;

Les noms de colonne étant différents entre les deux instructions "select", il est plus avantageux de référencer les colonnes de la clause ORDER BY en fonction de leur position dans le jeu de résultats. 

Dans cet exemple, nous avons trié les résultats par supplier_name/company_name par ordre croissant, comme indiqué par "ORDER BY 2".

Les champs supplier_name/company_name sont à la position n ° 2 du jeu de résultats

Tiré d'ici: http://www.techonthenet.com/sql/union.php

57
Anson Smith

En utilisant un exemple concret:

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

Des dossiers:

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

Dossiers:

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

Sortie souhaitée: (résultats de la première sélection en premier, à savoir les dossiers en premier)

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

SQL pour atteindre les résultats souhaités:

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

Voici un exemple de 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 clause ORDER BY doit simplement être la dernière déclaration, après que vous ayez terminé votre union. Vous pouvez réunir plusieurs ensembles, puis placer une clause ORDER BY après le dernier ensemble.

17
Todd Price
(SELECT table1.field1 FROM table1 
UNION
SELECT table2.field1 FROM table2) ORDER BY field1 

Travail? N'oubliez pas de penser ensembles. Obtenez l'ensemble que vous voulez en utilisant une union, puis effectuez vos opérations dessus.

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

(utilisez ALIAS)

4
MJ Latifi

C'est la chose la plus stupide que j'ai jamais vue, mais cela fonctionne et vous ne pouvez pas vous disputer avec les résultats.

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

L'intérieur de la table dérivée ne s'exécutera pas tout seul, mais fonctionnera parfaitement. J'ai essayé ceci sur SS 2000, SS 2005, SS 2008 R2, et les trois fonctionnent.

4
tlang

En parcourant cette section de commentaires, je suis tombé sur deux modèles différents répondant à la question. Malheureusement pour SQL 2012, le deuxième modèle ne fonctionne pas, alors voici mon "travail"


Trier par sur une colonne commune

C'est le cas le plus facile que vous puissiez rencontrer. Comme de nombreux utilisateurs l'ont fait remarquer, il suffit d'ajouter un Order By à la fin de la requête.

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

ou

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

Trier par sur différentes colonnes

Voici où cela devient réellement délicat. À l’aide de SQL 2012, j’ai essayé le poste principal et cela ne fonctionne pas.

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

Suite à la recommandation dans le commentaire, j'ai essayé ceci

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

Ce code a été compilé, mais DUMMY_ALIAS1 et DUMMY_ALIAS2 remplacent le Order By établi dans l'instruction Select, ce qui le rend inutilisable.

La seule solution à laquelle je pouvais penser, qui a fonctionné pour moi, n’utilisait pas un syndicat, mais consistait à faire en sorte que les requêtes soient traitées individuellement, puis à les traiter. Donc, en gros, ne pas utiliser une Union quand vous voulez Order By

2
Bubblesphere

Voici comment c'est fait

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
2
Prayut Parsekar

En utilisant order séparément, chaque sous-ensemble obtient un ordre, mais pas l'ensemble, ce que vous souhaiteriez en unissant deux tables.

Vous devriez utiliser quelque chose comme ceci pour avoir un ensemble ordonné:

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
1
Ernesto Morales

Si nécessaire pour conserver le tri interne:

SELECT 1 as type, field1 FROM table1 
UNION 
SELECT 2 as type, field1 FROM table2 
ORDER BY type, field1
0
user1795683
(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

Essaye ça. Cela a fonctionné pour moi. 

0
mandroid

La deuxième table ne peut pas inclure le nom de la table dans la clause ORDER BY.

Alors...

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

Ne jette pas une exception

0

Pour SQL Server 2014/2012/Autres (non vérifié):

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
0
Bimal Das