410013796724260
• Webmoney
R335386147728
Z369087728698
Объединение UNIONДля объединения результатов двух и более SQL-запросов SELECT в единую таблицу применяется ключевое слово UNION. Запросыдолжны возвращать одинаковое число и последовательность совместимых типов данных в соответствующих столбцах. Синтаксис применения SQL запроса UNIONОператор UNION размещается между SQL запросами : select user_id, userName, phone from users UNION [ALL] select city_id, cityName, region from cities UNION [ALL] select company_id, companyName, address from companies В представленном примере в одну кучу свалили информацию из трех таблиц, имеющих однотипные столбцы, что, конечно, неправильно, но это работает. UNION весьма полезен в случаях, когда требуется получить консолидированную информацию, разделенную на несколько одинаковых таблиц, например рабочая и архивная таблицы. В этом случае, с использованием UNION можно извлекать данные, сгруппированные по годам и месяцам, включая и текущий период, а также получить полную информацию, связанную с определенным объектом. UNION может быть использован совместно с оператором ALL для получения всех записей. Но необходимо отметить, что UNION ALL работает быстрее, чем просто UNION, поскольку при использовании оператора UNION проводится дополнительная фильтрация результата аналогичная SELECT DISTINCT, а при использовании UNION ALL — нет. Правила применения UNIONПри использовании UNION необходимо соблюдать несколько правил, регламентирующих порядок применения оператора :
Тип столбцов нескольких запросов может не совпадать, но обязательно должен быть совместимым путем неявного преобразования. Следует помнить, что столбцы с типом данных XML должны быть эквивалентными, т.е. тип столбцов должен быть определен либо в XML-схеме, либо быть нетипизированными. Типизированные столбцы должны относиться к одной и той же коллекции XML-схем. Выборка из двух таблиц с использованием UNIONВ качестве примера рассмотрим две простенькие таблицы (архивная и рабочая) без определения первичных и внешних ключей, индексов, ограничений на значения колонок и прочих "прелестей" SQL-языка. Допускаем, что в архивной таблице хранится информация о заказах за прошедшие годы. В рабочей таблице размещаются текущие продажи/заказы. Список товаров и услуг, входящих в заказ, не рассматриваем. Архивная таблица заказов : create table archive ( id int not null, -- идентификатор записи mid int not null, -- идентификатор менеджера year int not null, -- год month int not null, -- месяц total decimal(9,4) not null ); insert into archive (id, mid, year, month, total) values (1, 2, 2013, 1, 23500); insert into archive (id, mid, year, month, total) values (2, 2, 2013, 2, 11534); insert into archive (id, mid, year, month, total) values (3, 2, 2013, 3, 17532); insert into archive (id, mid, year, month, total) values (4, 2, 2013, 4, 23543); insert into archive (id, mid, year, month, total) values (5, 2, 2013, 5, 23245); Рабочая таблица заказов : create table orders ( id int not null, -- идентификатор заказа mid int not null, -- идентификатор менеджера total decimal(9,4) not null, data datetime not null ); insert into orders (id, mid, total, data) values (1, 1, 1350, '2014-02-23'); insert into orders (id, mid, total, data) values (2, 2, 3250, '2014-02-24'); Использование UNION ALLЗапрос выборки данных по продажам товаров (предоставлении услуг) по месяцам за весь период : select CONCAT(CONVERT(year, CHAR (4)), '.', CAST(month as CHAR(2))) AS data, total from archive UNION ALL select CONVERT(DATE_FORMAT(data, '%Y.%m'), CHAR (7)), SUM(total) from orders GROUP BY DATE_FORMAT(data, '%Y.%m') order by 1; Не следует относиться критично к конкатенации и функции преобразования даты; для различных СУБД это может различаться. Результат выполнения запроса : data total -------------------- 2013.1 23500.0000 2013.2 11534.0000 2013.3 17532.0000 2013.4 23543.0000 2013.5 23245.0000 2014.2 4600.0000 Использование UNIONЗапрос выборки данных по продажам товаров (предоставлении услуг) по месяцам за весь период для определенного менеджера : select CONCAT(CONVERT(year, CHAR (4)), '.', CAST(month as CHAR(2))) AS data, total from archive where mid = 2 UNION ALL select CONVERT(DATE_FORMAT(data, '%Y.%m'), CHAR (7)), SUM(total) from orders where mid = 2 GROUP BY DATE_FORMAT(data, '%Y.%m') order by 2; Результат выполнения запроса : data total -------------------- 2014.2 3250.0000 2013.2 11534.0000 2013.3 17532.0000 2013.5 23245.0000 2013.1 23500.0000 2013.4 23543.0000 Записи в результирующем наборе можно упорядочить с помощью одного или нескольких полей с использованием оператором ASC или DESC. Номер 1 и 2 в предложении ORDER BY указывает по какому столбцу результирующего набора будет упорядочен результат выборки. Так как столбцы объединения - это столбцы вывода, они не имеют имен, и следовательно, должны определяться по номеру. Этот номер указывает на их место среди других столбцов вывода. Внешнее объединение с UNIONПри помощи UNION можно создавать полные внешние объединения : SELECT e.id as eid, d.id as did, e.name as employee, d.name as department FROM employee e LEFT JOIN department d ON e.did = d.id UNION SELECT e.id as eid, d.id as did, e.name as employee, d.name as department FROM employee e RIGHT JOIN department d ON e.did = d.id; Иногда в запросы вставляют дополнительное отладочное поле, чтобы понять к какому SELECT относится текущая запись набора. SELECT e.id as eid, d.id as did, e.name as employee, d.name as department, 'first' FROM employee e LEFT JOIN department d ON e.did = d.id UNION SELECT e.id as eid, d.id as did, e.name as employee, d.name as department, 'second' FROM employee e RIGHT JOIN department d ON e.did = d.id; |