SQL-запит - Використання порядку за допомогою UNION


83

Як можна програмно відсортувати запит об’єднання, витягуючи дані з двох таблиць? Наприклад,

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

Кидає виняток

Примітка: це робиться на механізмі бази даних MS Access Jet

Відповіді:


118

Іноді вам потрібно мати ORDER BYв кожному з розділів, з яким потрібно поєднувати UNION.

В цьому випадку

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

1
спрацював для мене, коли порядок за впливає на набір результатів (як при використанні Top x)
Джеймс Баррас

Це саме те, що я шукаю! Дякую!
Srichand Yella

Мені чудово підходить ... потрібно переконатися, що зовнішній вибір має псевдонім таблиці. Це мене вкусило.
Троя

У мене не виникло проблем із використанням цього синтаксису з Microsoft SQL Server Standard (64-розрядна версія) 11.0.5058.0.
hlovdal

3
У SSMS вам потрібно буде змінити SELECT TOP 100 PERCENTORDER BY
підзапити

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

18
Це технічно не виконує того, що ви логічно задавали у вихідному питанні.
Ian Boyd

2
@Ian Boyd: Я розумію вашу думку, але те, що вони запитують, не має логічного сенсу: об’єднання діє на множинах, а множини не мають порядку!
день, коли

8
@onedaywhen Оригінальний автор хоче об'єднати два упорядковані набори результатів. UNIONне дозволяє цього статися. Для цього може бути інша конструкція. Там може і не бути. У будь-якому випадку ця відповідь технічно не виконує того, про що запитував автор.
Ян Бойд,

4
@Ian Boyd: У SQL ORDER BYє частиною курсора, тоді як UNIONпрацює з таблицями, тому їх код не може працювати. Я не бачу, як ви можете зробити висновок про намір ОП з абсурдного кодексу. Подумайте, що SQL UNIONвидаляє дублікати: якщо це ваші "впорядковані набори результатів" {1, 2, 3} UNION {2, 4, 6}, результатом буде {1, 2, 3, 4, 6}чи {1, 3, 2, 4, 6}? Ми не знаємо, оскільки об'єднання "впорядкованих наборів результатів" не визначено щодо SQL, а OP не вказано.
день, коли

Я використовую MYSQL, я включив поле (поле замовлення) у всі оператори select. Тоді щойно додав Order by by наприкінці, для мене це чудово працює.
CreativeManix

57

Я думаю, що це добре спрацьовує пояснення.

Нижче наведено запит UNION, який використовує речення 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;

Оскільки назви стовпців між двома операторами "select" відрізняються, вигідніше посилатися на стовпці в реченні ORDER BY за їх положенням у наборі результатів.

У цьому прикладі ми відсортували результати за зростанням supplier_name/ company_nameза зростанням, позначеним "ЗАМОВИТИ НА 2".

В supplier_name/ company_nameполях знаходяться в положенні # 2 в наборі результатів.

Взято звідси: http://www.techonthenet.com/sql/union.php


28

На конкретному прикладі:

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

Файли:

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

Папки:

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

Бажаний результат: (результати першого вибору спочатку, тобто папок спочатку)

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

SQL для досягнення бажаних результатів:

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

3
Це найкраща відповідь на сьогоднішній день
javier_domenech

1
Це ВЕЛИКА відповідь!
Алі Гонабаді

Примітка - ви повинні вказати похідну таблицю псевдонімом (як показано в цьому прикладі з dt), інакше вона не буде працювати. Я був здивований цим деякий час, оскільки я пропустив цю деталь для початку, і повідомлення про помилку, видане SSMS, не особливо корисно.
CactusCake

17

Ось приклад із 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;

Речення ORDER BY просто має бути останнім твердженням після того, як ви зробите все об’єднання. Ви можете об’єднати кілька наборів разом, а потім поставити речення ORDER BY після останнього набору.


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

Робота? Запам’ятайте набори думок. Отримайте набір, який ви хочете, використовуючи штуцер, а потім виконайте над ним свої операції.


Ви також можете використовувати порядкові значення у своєму порядку за пунктом на випадок, якщо поля, за якими ви хочете відсортувати, по-іншому названі
Ансон Сміт

5
SELECT table1Column1 as col1,table1Column2 as col2
    FROM table1
UNION
(    SELECT table2Column1 as col1, table1Column2 as col2
         FROM table2
)
ORDER BY col1 ASC

4
SELECT field1
FROM ( SELECT field1 FROM table1
       UNION
       SELECT field1 FROM table2
     ) AS TBL
ORDER BY TBL.field1

(використовуйте ПСИХІМ)


@DisplacedGuy, якщо MJ має кращу відповідь на запитання, то будь-яке із наведеного, і в цьому випадку у прийнятої відповіді явно є проблеми, тоді MJ повинен мати можливість, і я закликаю його залишити нові відповіді
MobileMon

До речі, відповідь MJ найкраща! (принаймні для мене)
MobileMon

4

Це найдурніше, що я коли-небудь бачив, але воно працює, і ви не можете сперечатися з результатами.

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

Інтер'єр похідної таблиці не буде виконуватися самостійно, але оскільки похідна таблиця працює абсолютно чудово. Я спробував це на SS 2000, SS 2005, SS 2008 R2, і всі три працюють.


2

Ось як це робиться

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

Переглядаючи цей розділ коментарів, я натрапив на дві різні моделі відповіді на запитання. На жаль, для SQL 2012 другий шаблон не працює, тому ось моя "робота навколо"


Замовити за спільною колонкою

Це найпростіший випадок, з яким ви можете зіткнутися. Як зазначали багато користувачів, все, що вам дійсно потрібно зробити, - це додати знак Order Byв кінці запиту

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

або

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

Замовлення за різними стовпцями

Ось де це насправді стає складним. Використовуючи SQL 2012, я спробував верхній пост, і він не працює.

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 * 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

Цей код справді скомпілював, але DUMMY_ALIAS1і DUMMY_ALIAS2замінює Order Byвстановлений у Selectзаяві, що робить його непридатним для використання.

Єдиним рішенням, яке я міг придумати і яке працювало для мене, було не використання об’єднання, а натомість змушення виконувати запити індивідуально, а потім мати справу з ними. Отже, в основному, не використовуючи, Unionколи ти хочешOrder By


1

Використовуючи порядок окремо, кожна підмножина отримує порядок, але не весь набір, саме для цього ви хотіли б об’єднати дві таблиці.

Ви повинні використовувати щось на зразок цього, щоб мати один замовлений набір:

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

0

Друга таблиця не може включати назву ORDER BYречення в пункт.

Тому...

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

Не кидає винятку


Яке це було гарне запитання. Чи можете ви сказати, чи ваша версія, чи вкладена, повертає бажані результати? Або вони обидва повертають однакові результати? Якщо так, то чи буде вкладене рішення (іншого хлопця) більш ефективним, оскільки воно ЗАМОВЛЯЄ лише один раз?
DOK,

Я не впевнений, що переваги продуктивності двигуна Jet, але я б сказав, що читабельність збільшується завдяки вкладенню.
Кертіс Індервіше,

0

При необхідності збереження внутрішньої сортування:

SELECT 1 as type, field1 FROM table1 
UNION 
SELECT 2 as type, field1 FROM table2 
ORDER BY type, field1

0
(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

Спробуйте це. У мене це спрацювало.


0

Для Sql Server 2014/2012 / Інші (Не перевірено):

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

Ви отримуєте помилку компіляції в 2012 році, намагаючись цю. Сценарій не буде працювати для збереженої процедури. Вам потрібен верхній речення.
Timothy Dooling
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.