Приведи пример SQL-подзапроса.

Ответ

Подзапрос — это запрос, вложенный в другой SQL-запрос. Он может использоваться в различных частях основного запроса.

Пример 1: Подзапрос в условии WHERE (с IN) Найти всех сотрудников, которые работают в отделах, расположенных в Лондоне.

SELECT employee_id, first_name, last_name
FROM employees
WHERE department_id IN (
    SELECT department_id
    FROM departments
    WHERE location_id = 'LON' -- Предположим, 'LON' это код Лондона
);

Пример 2: Коррелированный подзапрос в SELECT Для каждого сотрудника вывести его зарплату и среднюю зарплату по его отделу.

SELECT
    employee_id,
    first_name,
    salary,
    (
        SELECT AVG(salary)
        FROM employees e2
        WHERE e2.department_id = e1.department_id
    ) AS avg_department_salary
FROM employees e1;

Пример 3: Подзапрос как производная таблица (в FROM) Найти отделы со средней зарплатой выше средней по компании.

SELECT department_id, avg_sal
FROM (
    SELECT department_id, AVG(salary) AS avg_sal
    FROM employees
    GROUP BY department_id
) AS dept_avg
WHERE avg_sal > (
    SELECT AVG(salary) FROM employees
);

Ключевой момент: Подзапросы в WHERE и SELECT должны возвращать один столбец (или одно скалярное значение). Подзапрос в FROM должен иметь псевдоним (AS dept_avg).

Ответ 18+ 🔞

А, ну вот, подзапросы, ёпта! Это когда ты в одном запросе засовываешь другой запрос, как матрёшку. Типа «запрос в запросе», чтобы не делать два отдельных. Хитро, да? Сейчас разжуём.

Пример 1: Подзапрос в условии WHERE (с IN) Смотри, задача: найти всех работяг, которые трудятся в отделах, сидящих в Лондоне. Делаем так: сначала внутренним запросом выясняем, какие отделы (их department_id) вообще в Лондоне валяются. А потом внешним запросом выбираем всех, кто в этих отделах числится. Всё просто, как три копейки.

SELECT employee_id, first_name, last_name
FROM employees
WHERE department_id IN (
    SELECT department_id
    FROM departments
    WHERE location_id = 'LON' -- Допустим, 'LON' это и есть Лондон, ядрёна вошь
);

Пример 2: Коррелированный подзапрос в SELECT (самый интересный) Тут уже веселее. Хотим для каждого чувака не только его зарплату, но и среднюю по его же отделу, чтобы было с чем сравнить. Вот и лепим подзапрос прямо в список выборки. Он «коррелированный», потому что ссылается на поле (e1.department_id) из внешнего запроса. Для каждой строчки e1 этот подзапрос выполняется заново, считая среднюю только по его отделу. Компьютер, конечно, охуевает от нагрузки, но что поделать.

SELECT
    employee_id,
    first_name,
    salary,
    (
        SELECT AVG(salary)
        FROM employees e2
        WHERE e2.department_id = e1.department_id -- Вот эта связка — ключ!
    ) AS avg_department_salary
FROM employees e1;

Пример 3: Подзапрос как производная таблица (в FROM) А это уже высший пилотаж. Сначала внутренним запросом создаём виртуальную табличку: отдел и средняя зарплата в нём. А потом уже из этой таблички внешним запросом отбираем только те отделы, где средняя зарплата выше средней по всей конторе. Главное — не забыть дать этой виртуальной таблице псевдоним (AS dept_avg), а то СУБД начнёт материться, что не понимает, откуда данные брать.

SELECT department_id, avg_sal
FROM (
    SELECT department_id, AVG(salary) AS avg_sal
    FROM employees
    GROUP BY department_id
) AS dept_avg -- Без этого псевдонима — никуда, доверия ебать ноль!
WHERE avg_sal > (
    SELECT AVG(salary) FROM employees
);

Ключевой момент, который надо запомнить, чтобы не облажаться:

  • Если лепишь подзапрос в WHERE или в SELECT (как в примерах 1 и 2), он должен возвращать один столбец. А лучше вообще одно значение, скаляр. Иначе будет тебе, чувак, ошибка — овердохуища данных, а системе надо одну цифру или один список ID.
  • Если используешь подзапрос в FROM (как в примере 3) — это уже целая таблица. Но её обязательно надо назвать (дать псевдоним через AS). Без этого — сразу в пизду, SQL не примет.