Подзапросы и UNION
Вкладываем один запрос в другой (подзапросы) и склеиваем результаты через UNION.
Подзапрос — это
SELECTвнутри другого запроса; его результат используется как значение, список или таблица для внешнего запроса.
Подзапрос в WHERE
Самый частый случай — отобрать строки по результату другого запроса. Например, сотрудники с зарплатой выше средней.
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT,
salary INTEGER
);
INSERT INTO employees (name, salary) VALUES
('Анна', 120000), ('Борис', 90000),
('Вера', 80000), ('Глеб', 110000);
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
Вывод:
name salary Анна 120000 Глеб 110000
Внутренний запрос посчитал среднюю зарплату (100000), а внешний оставил тех, кто выше неё.
Подзапрос с IN
Подзапрос может вернуть список значений, по которому фильтрует IN. Найдём пользователей, у которых есть хотя бы один заказ.
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER
);
INSERT INTO users (name) VALUES ('Анна'), ('Борис'), ('Вера');
INSERT INTO orders (user_id) VALUES (1), (1), (3);
SELECT name
FROM users
WHERE id IN (SELECT user_id FROM orders);
Вывод:
name Анна Вера
UNION — склеить результаты
UNION объединяет строки двух запросов в один результат. Требование: одинаковое число столбцов совместимых типов. UNION убирает дубликаты, а UNION ALL — оставляет все строки (и работает быстрее).
CREATE TABLE clients (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE partners (id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO clients (name) VALUES ('Анна'), ('Борис');
INSERT INTO partners (name) VALUES ('Борис'), ('Глеб');
SELECT name FROM clients
UNION
SELECT name FROM partners
ORDER BY name;
Вывод:
name Анна Борис Глеб
«Борис» был в обеих таблицах, но UNION оставил его один раз. С UNION ALL он встретился бы дважды.
UNION против JOIN
Не путайте: JOIN соединяет таблицы по горизонтали (добавляет столбцы), а UNION — по вертикали (добавляет строки одинаковой структуры).
Итог
- Подзапрос —
SELECTвнутри другого запроса; часто стоит вWHEREили сIN. - Скалярный подзапрос (например,
AVG) даёт одно число для сравнения. UNIONсклеивает строки запросов и убирает дубли;UNION ALLоставляет все.- JOIN добавляет столбцы (по горизонтали), UNION — строки (по вертикали).