Як замовити за допомогою об'єднання в SQL?


201

Чи можна замовити, коли дані надходять від багатьох вибраних та об'єднати їх разом? Як от

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
Якщо ви маєте той самий стовпець у запиті об'єднання, то в кінці накажіть порядок за назвою стовпця.
anirban karak

Відповіді:


266

Просто напишіть

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

порядок by застосовується до повного набору результатів


45
Що робити, якщо я хочу, щоб сорт застосовувався лише у верхній частині Союзу?
marifrahman

7
@marifrahman побачити моя відповідь stackoverflow.com/a/43855496/2340825
BA TabNabber

2
@marifrahman вибачте копати стару тему, але це може допомогти іншим. Якщо ви хочете, щоб ЗАМОВЛЕННЯ було застосовано до першої частини Спілки, захистіть цей ВИБІР дужками.
Лідельн Кіоку

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. Єдине дозволене застереження за станом на кінець UNION, і воно стосується всього Союзу, що робить xxx UNION yyy ORDER BY zzzеквівалент(xxx UNION yyy) ORDER BY zzz
Nicholas Carey

39

Для того, щоб сортування було застосовано лише до першої заяви в Спілці, ви можете поставити його в підвідбірку разом з 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
@Nicholas Carey - коли я спочатку тестував за допомогою UNION, він поводився непередбачувано, як ви описали, я думаю, що СПІЛЬ ВСІХ (принаймні в Oracle) були необхідні для того, щоб замовити верх SELECT вище дна. Однак я надав альтернативний варіант, який гарантує правильне впорядкування і повинен бути незалежним від бази даних.
BA TabNabber

Не працює для мене. Той, хто має UNION ALL, все ще не підтримує порядок у першому SELECT.
Аміт Чигадані

І проблема з другим запитом полягає в тому, що він не усуває дублікатів записів. Тому що ви додали ще один стовпець "rowOrder", який може мати інше значення щодо дублікатів записів. Мета UNION проти UNION ALL втрачена.
Аміт Чігадані

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

12

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

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

зауважте, що я використовую поодинокі лапки в першому виділенні, але зворотні для інших.

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


що важливого ви хочете зробити, використовуючи одну пропозицію в першому виділенні, а зворотні посилання в іншій? В ідеалі воно повинно бути послідовним.
nanosoft

Перший вибір - буквальний; це заголовок, як "NAMES". Другий вибір - це посилання на таблицю. Таким чином, ваш перший рядок буде "NAMES", а решта рядків будуть фактичними іменами, вибраними з таблиці. Справа в тому, що ваш заголовок може бути таким самим рядком, що і назва стовпця, з якого ви вибираєте, і це рішення для використання потрібної мітки, без того, щоб вона стикалася у вашому союзі.
Євген Симкін

2
Після деяких експериментів я бачу, що псевдонім, згаданий у пункті ORDER BY, повинен бути зазначений у пунктах SELECT. Ви не можете сортувати за іншим стовпцем. Звичайно, ви можете обійти це, загорнувши всю річ у a, 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 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

Як зазначено в інших відповідях, "Порядок замовлення" після LAST Union повинен застосовуватися до обох наборів даних, об'єднаних об'єднанням.

У мене було два набори даних, але використовували різні таблиці, але однакові стовпці. "Замовлення" після 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.