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 06
3
В SSMS вам нужно будет изменить подзапросы SELECT TOP 100 PERCENTна, чтобы использовать их ORDER BYв подзапросе
Джозеф Нилдс,
64
SELECT field1 FROM table1
UNION
SELECT field1 FROM table2
ORDER BY field1
Анне Порософф
источник
18
Технически это не соответствует тому, что вы логически задавали в исходном вопросе.
Ian Boyd
2
@ Ян Бойд: Я понимаю вашу точку зрения, но то, о чем они спрашивают, не имеет логического смысла: union работает на множествах, а у множеств нет порядка!
однажды, когда
8
@onedaywhen Первоначальный автор хочет объединить два упорядоченных набора результатов. UNIONне позволяет этому случиться. Для этого может быть другая конструкция. Может и не быть. В любом случае этот ответ технически не соответствует тому, о чем спрашивал автор.
Ian Boyd
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, я включил поле (поле заказа) во все операторы выбора. Затем просто добавлен заказ по в конце, у меня отлично работает.
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в возрастающем порядке, как обозначено «ORDER BY 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
Это ОТЛИЧНЫЙ ответ!
Али Гонабади 02
Примечание. Вы должны дать производной таблице псевдоним (как показано в этом примере 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 

Работа? Не забывайте думать о наборах. Получите нужный набор, используя объединение, а затем выполните с ним свои операции.

Ник
источник
Вы также можете использовать порядковые значения в предложении order by в случае, если поля, которые вы хотите отсортировать, названы по-другому
Энсон Смит
5
SELECT table1Column1 as col1,table1Column2 as col2
    FROM table1
UNION
(    SELECT table2Column1 as col1, table1Column2 as col2
         FROM table2
)
ORDER BY col1 ASC
JohnMcG
источник
4
SELECT field1
FROM ( SELECT field1 FROM table1
       UNION
       SELECT field1 FROM table2
     ) AS TBL
ORDER BY TBL.field1

(используйте АЛИАС)

MJ Latifi
источник
@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

Bubblesphere
источник
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

Не генерирует исключение

Кертис Индервиеше
источник
Какой это был хороший вопрос. Можете ли вы сказать, ваша версия или вложенная версия возвращает желаемые результаты? Или они оба возвращают одинаковые результаты? Если да, будет ли вложенное решение (другого парня) более производительным, потому что оно выполняет ORDER BY только один раз?
DOK
Я не уверен в улучшении производительности двигателя Jet, но я бы сказал, что читаемость улучшилась из-за вложенности.
Curtis Inderwiesche
0

При необходимости сохранить внутреннюю сортировку:

SELECT 1 as type, field1 FROM table1 
UNION 
SELECT 2 as type, field1 FROM table2 
ORDER BY type, field1
пользователь1795683
источник
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 году, пытаясь это сделать. Сценарий не будет работать для хранимой процедуры. Вам нужно верхнее предложение.
Тимоти Дулинг