Оператор для работы с наборами UNION. Объединение UNION и UNION ALL в SQL – описание и примеры Примеры использования union и union all

В этом учебном материале вы узнаете, как использовать SQL оператор UNION ALL с синтаксисом и примерами.

Описание

SQL оператор UNION ALL используется для объединения результирующих наборов из 2 или более операторов SELECT. Он не удаляет повторяющиеся строки между различными операторами SELECT (возвращаются все строки).
Каждый оператор SELECT в UNION ALL должен иметь одинаковое количество полей в наборах результатов с одинаковыми типами данных.

В чем разница между UNION и UNION ALL?

  • Оператор UNION удаляет повторяющиеся строки.
  • UNION ALL не удаляет повторяющиеся строки

Синтаксис

Синтаксис для оператора UNION ALL в SQL.

Параметры или аргумент

expression1 , expression2 , expression_n Столбцы или расчеты, которые вы хотите получить tables Таблицы, из которых вы хотите получить записи. В предложении FROM должна быть указана хотя бы одна таблица WHERE conditions Необязательный. Условия, которые должны быть выполнены для записей, которые будут выбраны

Примечание

  • В обоих запросах SELECT должно быть одинаковое количество выражений
  • Соответствующие выражения должны иметь одинаковый тип данных в запросах SELECT. Например: expression1 должен иметь одинаковый тип данных как в первом, так и во втором операторе SELECT
  • Смотрите также оператор

Пример — одиночное поле с тем же именем

Давайте посмотрим, как использовать SQL оператор UNION ALL, который возвращает одно поле. В этом простом примере поле в обоих операторах SELECT будет иметь одинаковое имя и тип данных.
Например.

PgSQL

SELECT supplier_id

FROM suppliers

UNION ALL

SELECT supplier_id

FROM orders

ORDER BY supplier_id;

Этот SQL пример UNION ALL будет возвращать supplier_id несколько раз в наборе результатов, если это же значение появилось в таблицах suppliers и orders . SQL оператор UNION ALL не удаляет дубликаты. Если вы хотите удалить дубликаты, попробуйте использовать оператор UNION.
Теперь давайте рассмотрим этот пример, далее приведем некоторые данные.

И вы выполнили следующий оператор UNION ALL.

PgSQL

SELECT supplier_id FROM suppliers UNION ALL SELECT supplier_id FROM orders ORDER BY supplier_id;

Как видно из этого примера, UNION ALL взял все значения supplier_id из таблицы suppliers , а также из таблицы orders и возвратил комбинированный набор результатов. Дубликаты не были удалены, как вы можете видеть по значению supplier_id 2000, которое дважды появляется в наборе результатов.

Пример — разные имена полей

Нет необходимости, чтобы соответствующие столбцы в каждом операторе SELECT имели одинаковые имена, но они должны быть с одинаковыми соответствующими типами данных.
Если у вас нет одинаковых имен столбцов в операторах SELECT, это становится немного сложнее, особенно если вы хотите упорядочить результаты запроса, используя оператор ORDER BY.
Давайте посмотрим, как использовать оператор UNION ALL с разными именами столбцов, и упорядочить результаты запроса.
Например.

PgSQL

В этом SQL примере UNION ALL, поскольку имена столбцов в двух операторах SELECT различаются, более выгодно ссылаться на столбцы в предложении ORDER BY по их положению в наборе результатов. В этом примере мы отсортировали результаты по supplier_id / company_id в порядке возрастания, как обозначено ORDER BY 1 . Поля supplier_id / company_id находятся в позиции № 1 в наборе результатов.
Теперь давайте рассмотрим этот пример подробнее с данными.
Если у вас была таблица suppliers , заполненная следующими записями.

И вы выполнили следующий запрос содержащий UNION ALL.

Я уже писал о . И там вывод одной таблицы зависил от содержимого другой. Но бывает нужно, когда требуется полная независимость вывода одной таблицы от другой. Всё, что хочется - это просто в одном запросе вытащить записи сразу из нескольких таблиц , не более того. И вот для этого используется в SQL ключевое слово UNION .

Давайте с Вами разберём SQL-запрос с использованием UNION :

SELECT `login`, `amount` FROM `employers` UNION SELECT `login`, `amount` FROM `staff`;

Данный запрос вернёт логины и суммы на счетах всех работодателей и сотрудников некоего сайта. То есть данные были в разных таблицах, но их схожесть позволяет вывести их сразу. Отсюда, кстати, идёт правило использования UNION-запросов : число и порядок полей должно совпадать во всех частях запроса.

Таких UNION-частей может быть очень много, но самое главное после последнего UNION надо обязательно поставить точку с запятой .

Ещё одной хорошей особенностью UNION является отсутствие повторений. Например, если один и тот же человек находится и среди сотрудников, и среди работодателей, разумеется, с той же самой суммой на счету, то в выборке он будет не 2 раза, а только 1 , что, как правило, и требуется. А если всё-таки нужны повторения, то тогда есть UNION ALL :

SELECT `login`, `amount` FROM `employers` UNION ALL SELECT `login`, `amount` FROM `staff`;

Вот так используется достаточно простой оператор UNION в SQL-запросе , упрощающий процедуру вывода сразу из множества таблиц однотипных данных, что в свою очередь очень хорошо скажется на производительности.

Оператор языка SQL UNION предназначен для объединения результирующих таблиц базы данных, полученных с применением слова SELECT. Условие объединения результирующих таблиц: совпадение числа, порядка следования и типа данных столбцов. ORDER BY следует применять к результату объединения и размещать только в конце составного запроса. Оператор UNION имеет следующий синтаксис:

SELECT ИМЕНА_СТОЛБЦОВ (1..N) FROM ИМЯ_ТАБЛИЦЫ UNION SELECT ИМЕНА_СТОЛБЦОВ (1..N) FROM ИМЯ_ТАБЛИЦЫ

В этой конструкции объединяемые запросы могут иметь условия в секции WHERE, а могут не иметь их. При помощи оператора UNION можно объединить запросы на извлечение данных как из одной таблицы, так и из разных.

При использовании оператора UNION без слова ALL результат не содержит дубликатов, а со словом ALL - содержит дубликаты.

Итоги и индивидуальные значения в одной таблице с помощью оператора SQL UNION

Одним запросом можно вывести из таблицы индивидуальные значения столбцов, например, число лет, проработанных сотрудниками фирмы, размеры их заработной платы и другие. Другим запросом - с использованием агрегатных функций - можно получить, например, сумму заработных плат, получаемых сотрудниками отделов или занимающих те или иные должности, или среднее число лет трудового стажа (в таких запросах применяется группировка с помощью оператора GROUP BY).

А если нам требуется получить в одной таблице и сводку всех индивидуальных значений, и итоговые значения? Здесь на помощь приходит оператор SQL UNION, с помощью которого два запроса объединяются. К результату объединения требуется применить упорядочение, используя оператор ORDER BY. Для чего это необходимо, будет лучше понятно из примеров.

Пример 1. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос возвращает индивидуальные размеры заработной платы, упорядоченные по должностям:

SELECT Name, Job, Salary FROM STAFF ORDER BY Job

Name Job Salary
Sanders Mgr 18357.5
Marenghi Mgr 17506.8
Pernal Sales 18171.2
Doctor Sales 12322.4
Factor Sales 16228.7

Второй запрос вернёт суммарную заработную плату по должностям. Мы уже готовим этот запрос для соединения с первым, поэтому будем помнить, что условием соединения является равное число столбцов, совпадение их названий, порядка следования и типов данных. Поэтому включаем в таблицу с итогами также столбец Name с произвольным значением "Z-TOTAL":

SELECT "Z-TOTAL" AS Name, Job, SUM (Salary) AS Salary FROM STAFF GROUP BY Job

Результатом выполнения запроса будет следующая таблица:

Name Job Salary
Z-TOTAL Mgr 35864.3
Z-TOTAL Sales 46722.3

Теперь объединим запросы при помощи оператора UNION и применим оператору ORDER BY к результату объединения. Группировать следует по двум столбцам: должность (Job) и имя (Name), чтобы строки с итоговыми (суммарными) значениями, в которых значение имени - "Z-TOTAL", находились ниже строк с индивидуальными значениями. Объединение результатов запросов будет следующим:

(SELECT Name, Job, Salary FROM STAFF ) UNION (SELECT "Z-TOTAL" AS Name, Job, SUM (Salary) AS Salary FROM STAFF GROUP BY Job) ORDER BY Job, Name

Результатом выполнения запроса с оператором UNION будет следующая таблица, в которой каждая первая строка в каждой группе должностей будет содержать суммарную заработную плату сотрудников, работающих на этой должности:

Name Job Salary
Marenghi Mgr 17506.8
Sanders Mgr 18357.5
Z-TOTAL Mgr 35864.3
Doctor Sales 12322.4
Factor Sales 16228.7
Pernal Sales 18171.2
Z-TOTAL Sales 46722.3

Написать запросы с использованием UNION самостоятельно, а затем посмотреть решение

Пример 2. Данные - те же, что в примере 1, но задача немного посложнее. Требуется вывести в одной таблице не только индивидуальные размеры заработной платы, упорядоченные по должностям и суммарную заработную плату по должностям, но суммарную заработную плату по всем сотрудникам.

Пример 3. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Name (фамилия), Dept (номер отдела), и Years (длительность трудового стажа).

Name Dept Years
Sanders 20 7
Pernal 20 8
Marenghi 38 5
Doctor 20 5
Factor 38 8

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

Другие случаи объединения запросов к одной таблице с помощью оператора SQL UNION

Пример 4. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос нужен для получения данных о сотрудниках, заработная плата которых более 21000:

Результатом выполнения запроса будет следующая таблица:

Теперь требуются данные, в которых объединены критерии отбора, применённые в двух запросах. Объединяем запросы при помощи оператора UNION:

Результатом выполнения запроса с оператором UNION будет следующая таблица:

ID Name
10 Sanders
30 Marenghi
100 Plotz
140 Fraye
160 Molinare
240 Daniels
260 Jones

Запрос с оператором UNION может возвращать и большее количество столбцов, важно, повторимся, чтобы в объединяемых запросах число столбцов, порядок их следования и типы данных совпадали.

Пусть сначала требуется получить данные о категориях и частях категорий объявлений, в которых подано более 100 объявлений в неделю. Пишем следующий запрос:

Результатом выполнения запроса будет следующая таблица:

Результатом выполнения запроса будет следующая таблица:

Теперь требуется извлечь данные, которые соответствуют критериям и первого, и второго запросов. Объединяем запросы при помощи оператора UNION:

Результатом выполнения запроса будет следующая таблица:

Объединение результатов запросов к двум таблицам с помощью оператора SQL UNION

До сих пор мы рассматривали запросы с оператором UNION, в которых объединялись результаты из одной таблицы. Теперь будем объединять результаты из двух таблиц.

Пример 6. Есть база данных склада строительных материалов. В ней есть таблицы, содержащая данные об обоях. Таблица Vinil содержит данные о виниловых обоях, таблица Paper - о бумажных обоях. Требуется узнать данные о ценах обоев из одной и другой таблицы.

Чтобы извлечь не повторяющиеся данные о ценах на виниловые обои, составим запрос со словом DISTINCT:

SELECT DISTINCT Price FROM VINIL

Результатом выполнения запроса будет следующая таблица:

Теперь составим объединённый запрос с оператором UNION:

SELECT DISTINCT Price FROM VINIL UNION SELECT DISTINCT Price FROM PAPER

Так как мы не используем слово ALL, дубликаты значений 400, 500 и 530 выводиться не будут. Результатом выполнения запроса будет следующая таблица:

Price
300
320
360
400
430
500
530
610
720
800
850

Пример 7. База данных и таблицы - те же, что и в предыдущем примере.

Требуется получить все данные о ценах, в том числе повторяющиеся. Запрос на объединение результатов с использованием оператора UNION будет аналогичен запросу в предыдущем примере, но вместо просто UNION пишем UNION ALL:

SELECT DISTINCT Price FROM VINIL UNION ALL SELECT DISTINCT Price FROM PAPER

Результатом выполнения запроса будет следующая таблица:

Price
300
320
360
400
400
430
500
500
530
530
610
720
800
850

При помощи оператора SQL UNION можно объединить как простые запросы, так и запросы, содержащие подзапросы (вложенные запросы) . Рассмотрим соответствующий пример.

Пример 8. Есть база данных "Театр". В её таблице Play содержатся данные о постановках (названия - в столбце Name), в таблице Director - даные о режиссёрах (в столбце Fname - имя, в столбце Lname - фамилия). Первичный ключ таблицы Director - dir_id - идентификационный номер режиссёра. Dir_id также - внешний ключ таблицы Play, он ссылается на первичный ключ таблицы Director. Требуется вывести спектакли режиссеров John Barton и Trevor Nunn.

Решение. Объединим результаты двух запросов - один возвращает спектакли режиссёра John Barton, другой - режиссёра Trevor Nunn. А каждый из этих объединяемых запросов к таблице Play делаем с подзапросом к таблице Director, который возвращает dir_id по имени и фамилии режиссёра. Каждый внешний запрос принимает из вложенного запроса значение ключа dir_id и возвращает названия постановок (Name):

Реляционные базы данных и язык SQL

Оператор для работы с наборами данных UNION объединяет результирующие наборы двух и более запросов и показывает все строки всех запросов как один результирующий набор.

UNION относится к классу операторов для работы с наборами данных (set operator). К другим таким операторам относятся INTERSECT и ЕХСЕРТ (ЕХСЕРТ и MINUS являются функциональными эквивалентами, но ЕХСЕРТ входит в стандарт ANSI/ Все операторы для наборов данных используются для одновременного манипулирования результирующими наборами двух и более запросов, отсюда и их название.

Синтаксис S0L2003

Технических ограничений на количество запросов в операторе UNION не существует. Общий синтаксис следующий.

UNION

UNION

Ключевые слова

UNION

Показывает, что результирующие наборы будут объединены в один результирующий набор. Дубликаты строк по умолчанию удаляются.

ALL

Объединяются и дубликаты строк из всех результирующих наборов.

DISTINCT

Из результирующего набора удаляются дубликаты строк. Столбцы, содержащие значения NULL, считаются дубликатами. (Если ключевые слова ALL и DISTINCT не используются, по умолчанию принимается DISTINCT.)

Общие правила

Существует лишь одно важное правило, о котором следует помнить при использовании оператора UNION: порядок, количество и тип данных столбцов должны быть идентичны во всех запросах.

Типы данных не обязательно должны быть идентичны, но они должны быть совместимы. Например, типы CHAR и VARCHAR являются совместимыми. По умолчанию результирующий цабор использует размер наибольшего из совместимых типов, и в запросе, в котором объединяются три столбца типа CHAR - CHAR(5), CHAR(IO) и CHAR(12), результаты будут в формате CHAR(12), а в столбцы меньшего размера будут добавляться дополнительные пробелы.

Хотя согласно стандарту ANSI оператор INTERSECT имеет более высокий приоритет по сравнению с другими операторами для работы с наборами, на многих платформах эти операторы рассматриваются как имеющие одинаковый приоритет. Вы можете явным образом управлять приоритетом операторов, используя скобки. В противном случае СУБД, скорее всего, будет выполнять их в порядке слева направо.

Предложение DISTINCT может (в зависимости от платформы) потребовать существенных затрат производительности, поскольку при этом часто требуется дополнительный проход по результирующему набору для удаления дублирующихся записей. Предложение ALL для увеличения производительности можно указывать во всех случаях, когда не ожидается наличия дубликатов (или если дубликаты допустимы).

Согласно стандарту ANSI в запросе можно использовать только одно предложение ORDER BY. Ставьте его в конце последней инструкции SELECT. Чтобы избежать двусмысленности при указании столбцов и таблиц, обязательно присваивайте всем столбцам всех таблиц соответствующие псевдонимы. Тем не менее при указании имен столбцов в запросе SELECT … UNION используется только псевдоним из первого запроса. Например:

SELECT au_lname AS lastname, au_fname AS firstname FROM authors UNION SELECT emp_lname AS lastname, emp_fname AS firstname FROM employees ORDER BY lastname, firstname;

Кроме того, поскольку в запросах оператора UNION могут содержаться столбцы с совместимыми типами данных, возможны вариации поведения кода на разных платформах, особенно в том, что касается длины типа данных столбца. Например, если столбец au_fname первого запроса заметно длиннее столбца emplname второго запроса, то разные платформы могут применять разные правила определения используемой длины. Однако, как правило, платформы выбирают для результирующего набора более длинный (и менее ограниченный) тип данных.

Каждая СУРБД может применять свои собственные правила определения имени столбца, если столбцы в разных таблицах имеют разные имена. Как правило, используются имена из первого запроса.

DB2

Платформа DB2 поддерживает ключевые слова UNION и UNION ALL стандарта ANSI плюс предложение VALUES.

[, (выражение-!, выражение2, …)] […] […]

Позволяет указывать один или несколько наборов определяемых вручную значений для записей в объединенном результирующем наборе. Каждое из этих значений должно содержать в точности такое же число столбцов, как в запросах оператора UNION. Строки значений в результирующем наборе разделяются запятыми.

Хотя предложение UNION DISTINCT не поддерживается, функциональным эквивалентом является предложение UNION. Предложение CORRESPONDING не поддерживается.

С ключевым словом UNION нельзя использовать такие типы данных, как VARCHAR, LONG VARGRAPHIC, BLOB, CLOB, DBCLOB, DATALINK, и структурные типы (но их можно использовать с предложением UNION ALL).

Если во всех таблицах используется одно имя столбца, в результирующем наборе используется это имя. Если же имена столбцов различаются, то DB2 генерирует новое имя столбца. После этого этот столбец нельзя использовать в предложении ORDER BY или предложении FOR UPDATE.

Если в одном запросе используется несколько операторов для наборов данных, то первыми выполняются те, которые заключены в скобки. После этого операторы выполняются в порядке слева направо. Однако все операции INTERSECT выполняются до операций UNION или ЕХСЕРТ. Например:

SELECT empno FROM employee WHERE workdept LIKE "E%" UNION SELECT empno FROM emp_act WHERE projno IN ("IF1000", "IF2000", "AD3110") UNION VALUES ("AA0001), (AB0002"), ("AC0003")

В этом примере мы получаем все ID сотрудников из таблицы employee, которые состоят в любом департаменте, с названием, начинающимся с «Е», а также ID всех сотрудников из бухгалтерской таблицы emp_act, которые работают в проектах IF1000", "IF2000", and "AD3110". Кроме того, сюда всегда включаются ID сотрудников "AA000T, "АВ0002", and "АС00031.

MySQL

Не поддерживается.

Oracle

Платформа Oracle поддерживает ключевые слова UNION и UNION ALL стандарта SQL ANSI. Синтаксис следующий.

Oracle не поддерживает предложение CORRESPONDING. Предложение UNION DISTINCT не. поддерживается, но функциональным эквивалентом является предложение UNION. Платформа Oracle не поддерживает использование предложений UNION ALL и UNION в следующих ситуациях.

Если первый запрос в операторе содержит какие-либо выражения в списке элементов, то присвойте этому столбцу псевдоним при помощи предложения AS. Кроме того, только последний запрос в операторе может содержать предложение ORDER BY. Например, вы можете получить все уникальные идентификаторы магазинов (store_id), без дубликатов используя следующий запрос.

SELECT stor_id FROM stores UNION SELECT stor_id FROM sales;

PostgreSQL

Платформа PostgreSQL поддерживает ключевые слова UNION и UNION ALL стандартного синтаксиса ANSI.

инструкция SElECT 2 UNION

Платформа PostgreSQL не поддерживает использование предложений UNION и UNION ALL в запросах с предложением FOR UPDATE. PostgreSQL не поддерживает предложение CORRESPONDING. Предложение UNION DISTINCT не поддерживается, по функциональным эквивалентом является предложение UNION.

Первый запрос в операторе не может содержать предложения ORDER BY или LIMIT. Последующие запросы с предложениями UNION и UNION ALL могут содержать эти предложения, но такие запросы нужно заключать в скобки. В противном случае расположенное справа предложение ORDER BY или LIMIT будет применяться ко всей операции.

SELECT a.au_lname FROM authors AS a WHERE a.au_lnanie LIKE "P%" UNI0N SELECT e.lname FROM employee AS e WHERE e.lname LIKE "P%";

SQL Server

Платформа SQL Server поддерживает ключевые слова UNION и UNION ALL стандартного синтаксиса ANSI.

инструкция SELECT 1 UNION

инструкция SELECT 2 UNION

SQL Server не поддерживает предложение CORRESPONDING. Предложение UNION DISTINCT не поддерживается, но функциональным эквивалентом является предложение UNION.

С предложениями UNION и UNION ALL вы можете использовать инструкцию SELECT…INTO, но ключевое слово INTO должно находиться в первом запросе оператора объединения. Специальные ключевые слова, такие, как SELECT ТОР и GROUP BY…WITH CUBE, можно использовать во всех запросах объединения. Однако обязательно включайте эти предложения во все запросы объединения. Если вы используете предложения SELECT ТОР или GROUP BY… WITH CUBE в одном запросе, операция выполнена не будет.

Все запросы в объединении должны содержать одно и то же количество столбцов. Типы данных столбцов не обязательно должны быть идентичны, но они должны быть неявным образом приводимы друг к другу. Например, совместное применение столбцов CHAR и VARCHAR допускается. При выводе данных SQL Server при определении размера типа данных для столбца результирующего набора использует размер наибольшего столбца. Таким образом, если в инструкции SELECT… UNION используются столбцы CHAR(5) и CHAR(IO), то данные обоих столбцов будут выводиться в столбце CHAR(IO). Числовые типы данных приводятся и отображаются в виде типа с наибольшей точностью.

Например, в следующем запросе объединяются результаты двух независимых запросов, использующих предложение GROUP BY…WITH CUBE.

В большинстве SQL-запросов используется один оператор, с помощью которого возвращаются данные из одной или нескольких таблиц. SQL также позволяет выполнять одновременно несколько отдельных запросов и отображать результат в виде единого набора данных. Такие комбинированные запросы обычно называют сочетаниями или сложными запросами .

1. Использование оператора UNION

Запросы в языке SQL комбинируются с помощью оператора UNION . Для этого необходимо указать каждый запрос SELECT и разместить между ними ключевое слово UNION . Ограничений по количеству использованного оператора UNION в одном общем запросе нет. В предыдущем разделе мы отмечали, что Access не имеет возможности создавать полное внешнее объединение , теперь мы посмотрим, как можно этого достичь через оператор UNION .

SELECT *
FROM Sumproduct LEFT JOIN Sellers ON Sumproduct.City = Sellers.City
UNION
SELECT *

FROM Sumproduct RIGHT JOIN Sellers ON Sumproduct.City = Sellers.City

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

Также стоит отметить, что во многих случаях вместо UNION мы можем использовать предложение WHERE со многими условиями, и получать аналогичный результат. Однако из-за UNION записи выглядят более лаконичными и понятными. Также необходимо соблюдать определенные правила при написании комбинированных запросов:

  • запрос UNION должен включать два и более операторов SELECT , отделенных между собой ключевым словом UNION (т.е. если в запросе используется четыре оператора SELECT, то должно быть три ключевых слова UNION)
  • каждый запрос в операторе UNION должен иметь одни и те же столбцы, выражения или статистические функции, которые, к тому же, должны быть перечислены в одинаковом порядке
  • типы данных столбцов должны быть совместимыми. Они не обязательно должны быть одного типа, однако обязаны иметь подобный тип, чтобы СУБД могла их однозначно преобразовать (например, это могут быть различные числовые типы данных или различные типы даты).

2. Включение или выключение повторяющихся строк

Запрос с UNION автоматически удаляет все повторяющиеся строки из набора результатов запроса (то есть, ведет себя как предложения WHERE с несколькими условиями в одном операторе SELECT ). Такое поведение оператора UNION по умолчанию, но при желании мы можем изменить это. Для этого нам следует использовать оператор UNION ALL вместо UNION .

3. Сортировка результатов комбинированных запросов

Результаты выполнения оператора SELECT сортируются с помощью предложения ORDER BY . При комбинировании запросов с помощью UNION только одно предложение ORDER BY может быть использовано, и оно должно быть проставлено в последнем операторе SELECT . Действительно, на практике нет особого смысла часть результатов сортировать в одном порядке, а другую часть - в другом. Поэтому несколько предложений ORDER BY применять не разрешается.