Как заказать с объединением в SQL?


202

Можно ли заказать, когда данные поступают от многих избранных и объединить их вместе? Такие как

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"

Как я могу заказать этот запрос по имени.

Некоторые говорили, что вы можете сделать запрос похожим

Select id,name,age
From Student
Where age < 15 or name like "%a%"
Order by name

Но в этом случае я просто игнорирую это решение.


1
Если у вас есть тот же столбец в запросе объединения, то в конце установите порядок по имени вашего столбца.
Анирбан Карак

Ответы:


266

Просто пиши

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"
Order by name

порядок по применяется к полному набору результатов


45
Что, если я хочу, чтобы сортировка применялась только к верху UNION?
marifrahman

7
@marifrahman см. мой ответ stackoverflow.com/a/43855496/2340825
BA TabNabber

2
@marifrahman извините, чтобы вырыть старую тему, но это может помочь другим. Если вы хотите, чтобы ORDER BY был применен к первой части UNION, защитите этот SELECT круглыми скобками.
Лидельн Кёку

82
Select id,name,age
from
(
   Select id,name,age
   From Student
   Where age < 15
  Union
   Select id,name,age
   From Student
   Where Name like "%a%"
) results
order by name

46
Как указывал bernd_k, по определению отдельные SELECT, составляющие UNION, не могут содержать предложение ORDER BY. Единственное допустимое условие ORDER BY находится в конце UNION и применяется ко всему UNION, что делает xxx UNION yyy ORDER BY zzzего эквивалентным(xxx UNION yyy) ORDER BY zzz
Николас Кэри

39

Чтобы применить сортировку только к первому оператору в UNION, вы можете поместить его в подвыбор с помощью UNION ALL (оба они необходимы в Oracle):

Select id,name,age FROM 
(    
 Select id,name,age
 From Student
 Where age < 15
 Order by name
)
UNION ALL
Select id,name,age
From Student
Where Name like "%a%"

Или (обращаясь к комментарию Николаса Кэри) вы можете гарантировать, что верхний SELECT упорядочен, а результаты отображаются над нижним SELECT следующим образом:

Select id,name,age, 1 as rowOrder
From Student
Where age < 15
UNION
Select id,name,age, 2 as rowOrder
From Student
Where Name like "%a%"
Order by rowOrder, name

4
Да. Это упорядочивает результаты подселекта. Это НЕ упорядочивает результаты selectоператора, ссылающегося на этот подпункт. Согласно стандарту SQL порядок результатов не определен, за исключением явного order byпредложения. Это первое selectв вашем примере, вероятно, возвращает свои результаты в порядке, возвращенном подвыбором, но это не гарантируется. Кроме того, это не * гарантирует * порядок упорядочения результирующего набора целиком union(то же правило в Стандарте). Если вы зависите от порядка, вас, в конце концов, укусят.
Николас Кэри

1
@ Николас Кэри - когда я первоначально тестировал с использованием UNION, он вел себя непредсказуемо, как вы описали, я думаю, что UNION ALL (по крайней мере, в Oracle) был необходим, чтобы расположить верхнюю часть SELECT над нижней. Однако я предоставил альтернативу, которая гарантирует правильный порядок и должна быть независимой от базы данных.
BA TabNabber

Не работает для меня Тот, у которого есть UNION ALL, по-прежнему не может поддерживать порядок в первом SELECT.
Амит Чигадани

И проблема со вторым запросом состоит в том, что он не удаляет дубликаты записей. Потому что вы добавили еще один столбец 'rowOrder', который может иметь другое значение в сравнении с дублирующимися записями. Цель СОЮЗА против СОЮЗА ВСЕ потеряна.
Амит Чигадани

1
@AmitChigadani Устранение дубликатов не было частью первоначального вопроса, но для этого предложения WHERE могут быть изменены для обеспечения уникальности. Например: где Имя, например, "% a%" И возраст> = 15
BA TabNabber

12

Оба других ответа верны, но я подумал, что стоит отметить, что место, где я застрял, не понимает, что вам потребуется порядок по псевдониму, и убедитесь, что псевдоним одинаков для обоих вариантов выбора ...

select 'foo'
union
select item as `foo`
from myTable
order by `foo`

обратите внимание, что я использую одинарные кавычки в первом выборе, но для других используется обратная галочка.

Это даст вам необходимую сортировку.


Что вы хотите сделать, используя одинарные кавычки в первом выборе и обратные галочки в другом? В идеале это должно быть последовательным.
Nanosoft

Первый выбор является литералом; это заголовок типа «Имена». Второй выбор - это ссылка на таблицу. Таким образом, ваша первая строка будет называться «NAMES», а остальные строки будут фактическими именами, выбранными из таблицы. Дело в том, что ваш заголовок вполне может быть той же строкой, что и имя столбца, из которого вы выбираете, и это решение для использования нужной вам метки без ее коллизии в вашем объединении.
Евгений Симкин

2
После некоторых экспериментов я вижу, что псевдоним, упомянутый в предложении ORDER BY, должен быть упомянут в предложениях SELECT. Вы не можете сортировать по другому столбцу. Конечно, вы можете обойти это, обернув все это в, SELECT a, b, c FROM (<insert union query here>) AS x;если вы действительно хотите избежать возврата дополнительного столбца.
Водин

11

Order Byприменяется после union, так что просто добавьте order byпредложение в конце операторов:

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like '%a%'
Order By name

9

Если я хочу, чтобы сортировка применялась только к одному из UNION, если используется Union all:

Select id,name,age
From Student
Where age < 15
Union all
Select id,name,age
From 
(
Select id,name,age
From Student
Where Name like "%a%"
Order by name
)

8

Как указывалось в других ответах, 'Order by' после LAST Union должен применяться к обоим наборам данных, к которым присоединяется union.

У меня было два набора данных, но с использованием разных таблиц, но одинаковых столбцов. «Order by» после того, как LAST Union все еще не работал. Использование ALIAS для столбца, используемого в порядке упорядочения, добилось цели.

Select Name, Address for Employee 
Union
Select Customer_Name, Address from Customer
order by customer_name;   --Won't work

Поэтому решение - использовать псевдоним 'User_Name':

Select Name as User_Name, Address for Employee 
Union
Select Customer_Name as User_Name, Address from Customer
order by User_Name; 

-1

Можно использовать это:

Select id,name,age
From Student
Where age < 15
Union ALL
SELECT * FROM (Select id,name,age
From Student
Where Name like "%a%")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.