Как применять оператор SQL UNION для объединения результатов запросов
Оператор языка SQL UNION предназначен для объединения результирующих таблиц базы данных, полученных с применением слова SELECT. Условие объединения результирующих таблиц: совпадение числа, порядка следования и типа данных столбцов. ORDER BY следует применять к результату объединения и размещать только в конце составного запроса. Оператор UNION имеет следующий синтаксис:
В этой конструкции объединяемые запросы могут иметь условия в секции WHERE, а могут не иметь их. При помощи оператора UNION можно объединить запросы на извлечение данных как из одной таблицы, так и из разных.
При использовании оператора UNION без слова ALL результат не содержит дубликатов, а со словом ALL — содержит дубликаты.
Итоги и индивидуальные значения в одной таблице с помощью оператора SQL UNION
Одним запросом можно вывести из таблицы индивидуальные значения столбцов, например, число лет, проработанных сотрудниками фирмы, размеры их заработной платы и другие. Другим запросом — с использованием агрегатных функций — можно получить, например, сумму заработных плат, получаемых сотрудниками отделов или занимающих те или иные должности, или среднее число лет трудового стажа (в таких запросах применяется группировка с помощью оператора GROUP BY).
А если нам требуется получить в одной таблице и сводку всех индивидуальных значений, и итоговые значения? Здесь на помощь приходит оператор SQL UNION, с помощью которого два запроса объединяются. К результату объединения требуется применить упорядочение, используя оператор ORDER BY. Для чего это необходимо, будет лучше понятно из примеров.
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке.
Пример 1. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. В ней есть столбцы Salary (размер заработной платы), Job (должность) и Years (длительность трудового стажа). Первый запрос возвращает индивидуальные размеры заработной платы, упорядоченные по должностям:
Результатом выполнения запроса будет следующая таблица:
| 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’:
Результатом выполнения запроса будет следующая таблица:
| Name | Job | Salary |
| Z-TOTAL | Mgr | 35864.3 |
| Z-TOTAL | Sales | 46722.3 |
Теперь объединим запросы при помощи оператора UNION и применим оператору ORDER BY к результату объединения. Группировать следует по двум столбцам: должность (Job) и имя (Name), чтобы строки с итоговыми (суммарными) значениями, в которых значение имени — ‘Z-TOTAL’, находились ниже строк с индивидуальными значениями. Объединение результатов запросов будет следующим:
Результатом выполнения запроса с оператором 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:
Результатом выполнения запроса будет следующая таблица:
| ID | Name |
| 140 | Fraye |
| 160 | Molinare |
| 260 | Jones |
Второй запрос возвращает имена сотрудников, должность которых «менеждер», а число лет трудового стажа — менее 8:
Результатом выполнения запроса будет следующая таблица:
| ID | Name |
| 10 | Sanders |
| 30 | Marenghi |
| 100 | Plotz |
| 140 | Fraye |
| 160 | Molinare |
| 240 | Daniels |
Теперь требуются данные, в которых объединены критерии отбора, применённые в двух запросах. Объединяем запросы при помощи оператора UNION:
Результатом выполнения запроса с оператором UNION будет следующая таблица:
| ID | Name |
| 10 | Sanders |
| 30 | Marenghi |
| 100 | Plotz |
| 140 | Fraye |
| 160 | Molinare |
| 240 | Daniels |
| 260 | Jones |
Запрос с оператором UNION может возвращать и большее количество столбцов, важно, повторимся, чтобы в объединяемых запросах число столбцов, порядок их следования и типы данных совпадали.
Теперь работаем с базой данных «Портал объявлений — 1». Скрипт для создания этой базы данных, её таблицы и заполения таблицы данных — в файле по этой ссылке
Пример 5. Есть база данных портала объявлений.
Пусть сначала требуется получить данные о категориях и частях категорий объявлений, в которых подано более 100 объявлений в неделю. Пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
| Category | Part | Units | Money |
| Транспорт | Автомашины | 110 | 17600 |
| Транспорт | Мотоциклы | 131 | 20960 |
| Электротехника | Телевизоры | 127 | 8255 |
| Электротехника | Холодильники | 137 | 8905 |
| Стройматериалы | Регипс | 112 | 11760 |
| Досуг | Музыка | 117 | 7605 |
Теперь требуется извлечь данные о категориях и частях категорий объявлений, за которые выручено более 10000 денежных единиц в неделю. Пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
| Category | Part | Units | Money |
| Транспорт | Автомашины | 110 | 17600 |
| Недвижимость | Квартиры | 89 | 18690 |
| Недвижимость | Дачи | 57 | 11970 |
| Транспорт | Мотоциклы | 131 | 20960 |
| Стройматериалы | Регипс | 112 | 11760 |
Теперь требуется извлечь данные, которые соответствуют критериям и первого, и второго запросов. Объединяем запросы при помощи оператора UNION:
Результатом выполнения запроса будет следующая таблица:
| Транспорт | Автомашины | 110 | 17600 |
| Транспорт | Мотоциклы | 131 | 20960 |
| Недвижимость | Квартиры | 89 | 18690 |
| Недвижимость | Дачи | 57 | 11970 |
| Электротехника | Телевизоры | 127 | 8255 |
| Электротехника | Холодильники | 137 | 8905 |
| Стройматериалы | Регипс | 112 | 11760 |
| Досуг | Музыка | 117 | 7605 |
Примеры запросов к базе данных «Портал объявлений-1» есть также в уроках об операторах INSERT, UPDATE, DELETE, HAVING.
How do I combine 2 select statements into one?
I have a table with lots of rows and columns of course 😛 Lets say it looks like this:
Now I want to create an advanced select statement that gives me this combined (pseudo SQLish here):
The output would be:
How would I combine those two select statements into one nice select statement?
Would it work if I complicated the SQL like below (because my own SQL statement contains an exists statement)? I just want to know how I can combine the selects and then try to apply it to my somewhat more advanced SQL.
My REAL SQL statement is this one:
which gives me a result. But I want to combine it with a copy of this select statement with an added AND on the end and the ‘Status’ field would be changed with a string like ‘DELETED’.
Соединение и объединение таблиц в SQL: операторы JOIN,UNION, INTERSECT и EXCEPT
Соединение таблиц в запросе SELECT выполняется с помощью оператора JOIN.
Возможно также выполнить соединение и без оператора JOIN с помощью инструкции WHERE используя столбцы соединения, но этот синтаксис считается неявным и устаревшим.
Выделяют следующие виды соединения, каждому из которых соответствует своя форма оператора JOIN:
- CROSS JOIN — перекрестное или декартово соединение
- [INNER] JOIN — естественное или внутреннее соединение
- LEFT [OUTER] JOIN — левое внешнее соединение
- RIGHT [OUTER] JOIN — правое внешнее соединение
- FULL [OUTER] JOIN — полное внешнее соединение
Существует также тета-соединение, самосоединение и полусоединение.
Естественное соединение
Естественное соединение — внутреннее соединение или соединение по эквивалентности.
Здесь предложение FROM определяет соединяемые таблицы и в нем явно указывается тип соединения — INNER JOIN. Предложение ON является частью предложения FROM и указывает соединяемые столбцы. Выражение employee.dept_no = department.dept_no определяет условие соединения.
Эквивалентный запрос с применением неявного синтаксиса:
Соединяемые столбцы должны иметь идентичную семантику, т.е. оба столбца должны иметь одинаковое логическое значение. Соединяемые столбцы не обязательно должны иметь одинаковое имя (или даже одинаковый тип данных), хотя часто так и бывает.
Соединяются только строки имеющие одинаковое значение в соединяемых столбцах. Строки, не имеющие таких одинаковых значений в результирующий набор вообще не попадут.
В инструкции SELECT объединить можно до 64 таблиц (ограничение MS SQL), при этом один оператор JOIN соединяет только две таблицы:
Декартово произведение (перекрестное соединение)
Декартово произведение (перекрестное соединение) соединяет каждую строку первой таблицы с каждой строкой второй. Результатом декартово произведения первой таблицы с n строками и второй таблицы с m строками будет таблица с n × m строками.
Внешнее соединение
Внешнее соединение позволяет в отличие от внутреннего извлечь не только строки с одинаковыми значениями соединяемых столбцов, но и строки без совпадений из одной или обеих таблиц.
Выделяют три вида внешних соединений:
-
левое внешнее соединение — в результирующий набор попадают все строки из таблицы с левой стороны оператора сравнения (независимо от того имеются ли совпадающие строки с правой стороны), а из таблицы с правой стороны — только строки с совпадающими значениями столбцов. При этом если для строки из левой таблицы нет соответствий в правой таблице, значениям строки в правой таблице будут присвоены NULL
Тета-соединение
Условие сравнения столбцов соединения не обязательно должно быть равенством, но может быть любым другим сравнением. Соединение, в котором используется общее условие сравнения столбцов соединения, называется тета-соединением:
Самосоединение
Самосоединение — это естественное соединение таблицы с самой собой. При этом один столбец таблицы сравнивается сам с собой. Сравнивание столбца с самим собой означает, что в предложении FROM инструкции SELECT имя таблицы употребляется дважды. Поэтому необходимо иметь возможность ссылаться на имя одной и той же таблицы дважды. Это можно осуществить, используя, по крайней мере, один псевдоним. То же самое относится и к именам столбцов в условии соединения в инструкции SELECT. Для того чтобы различить столбцы с одинаковыми именами, необходимо использовать уточненные имена.
Полусоединение
Полусоединение похоже на естественное соединение, но возвращает только набор всех строк из одной таблицы, для которой в другой таблице есть одно или несколько совпадений.
Оператор UNION
Оператор UNION объединяет результаты двух или более запросов в один результирующий набор, в который входят все строки, принадлежащие всем запросам в объединении:
Как объединить 2 запроса в sql
You can combine multiple queries using the set operators UNION , UNION ALL , INTERSECT , and MINUS . All set operators have equal precedence. If a SQL statement contains multiple set operators, then Oracle Database evaluates them from the left to right unless parentheses explicitly specify another order.
The corresponding expressions in the select lists of the component queries of a compound query must match in number and must be in the same data type group (such as numeric or character).
If component queries select character data, then the data type of the return values are determined as follows:
If both queries select values of data type CHAR of equal length, then the returned values have data type CHAR of that length. If the queries select values of CHAR with different lengths, then the returned value is VARCHAR2 with the length of the larger CHAR value.
If either or both of the queries select values of data type VARCHAR2 , then the returned values have data type VARCHAR2 .
If component queries select numeric data, then the data type of the return values is determined by numeric precedence:
If any query selects values of type BINARY_DOUBLE , then the returned values have data type BINARY_DOUBLE .
If no query selects values of type BINARY_DOUBLE but any query selects values of type BINARY_FLOAT , then the returned values have data type BINARY_FLOAT .
If all queries select values of type NUMBER , then the returned values have data type NUMBER .
In queries using set operators, Oracle does not perform implicit conversion across data type groups. Therefore, if the corresponding expressions of component queries resolve to both character data and numeric data, Oracle returns an error.
Table 2-8 for more information on implicit conversion and «Numeric Precedence» for information on numeric precedence
The following query is valid:
This is implicitly converted to the following compound query:
The following query returns an error:
Restrictions on the Set Operators
The set operators are subject to the following restrictions:
The set operators are not valid on columns of type BLOB , CLOB , BFILE , VARRAY , or nested table.
The UNION , INTERSECT , and MINUS operators are not valid on LONG columns.
If the select list preceding the set operator contains an expression, then you must provide a column alias for the expression in order to refer to it in the order_by_clause .
You cannot also specify the for_update_clause with the set operators.
You cannot specify the order_by_clause in the subquery of these operators.
You cannot use these operators in SELECT statements containing TABLE collection expressions.
To comply with emerging SQL standards, a future release of Oracle will give the INTERSECT operator greater precedence than the other set operators. Therefore, you should use parentheses to specify order of evaluation in queries that use the INTERSECT operator with other set operators.
The following statement combines the results of two queries with the UNION operator, which eliminates duplicate selected rows. This statement shows that you must match data type (using the TO_CHAR function) when columns do not exist in one or the other table:
UNION ALL Example
The UNION operator returns only distinct rows that appear in either result, while the UNION ALL operator returns all rows. The UNION ALL operator does not eliminate duplicate selected rows:
A location_id value that appears multiple times in either or both queries (such as ‘ 1700 ‘) is returned only once by the UNION operator, but multiple times by the UNION ALL operator.
The following statement combines the results with the INTERSECT operator, which returns only those unique rows returned by both queries:
The following statement combines results with the MINUS operator, which returns only unique rows returned by the first query but not by the second: