Подзапросы

Открыта

Вложенные запросы в SQL

Язык SQL позволяет вкладывать одни запросы в другие запросы. Это дает возможность написать один очень большой запрос, который будет делать что-то большое и сложное, хотя при этом читабельность кода значительно снижается.

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

  • Подзапрос возвращает одно единственное значение (одна колонка и одна строка).
  • Подзапрос возвращает список значений (таблица с одной колонкой).
  • Подзапрос возвращает таблицу (много колонок, любое количество строк).

Давай разберем по одному примеру для каждого случая.

Подзапрос со скалярным результатом

Давай найдем список всех наших сотрудников из таблицы employee, чья зарплата выше средней по компании. Как нам это сделать?

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

SELECT AVG(salary) FROM employee 

Тогда MySQL вернул нам значение: 76833.3333.

Как теперь найти список всех сотрудников, чья зарплата выше средней? Тоже очень просто:

 SELECT * FROM employee WHERE salary > 76833.3333 

Результат этого запроса будет таким:

id name occupation salary
1 Иванов Иван Программист 100000
2 Петров Петр Программист 80000
4 Рабинович Мойша Директор 200000

А теперь мы просто совместим оба запроса, подставив вместо значения 76833 первый запрос:

 SELECT * FROM employee WHERE salary > (SELECT AVG(salary) FROM employee) 

Результат этого запроса будет таким же:

id name occupation salary
1 Иванов Иван Программист 100000
2 Петров Петр Программист 80000
4 Рабинович Мойша Директор 200000

Подзапрос со списком значений

Помнишь когда-то давно у нас была задача – найти все записи из одной таблицы, для которых нет соответствующих записей из другой?

Там еще была такая картинка:

Если не ошибаюсь, то задание звучит так: отобразите список всех сотрудников из таблицы employee, для которых нет задач в таблице task.

Давай тоже найдем решение в два этапа.

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

  • убрать дубликаты – используйте ключевое слово DISTINCT.
  • уберите NULL-значения из результата.
SELECT DISTINCT employee_id FROM task WHERE employee_id IS NOT NULL

И вот мы получили красивый результат такого запроса:

employee_id
1
2
5
4
6

Давай для удобства временно запишем его в виде последовательности: 1,2,5,4,6. Теперь напишем второй запрос – к таблице employee, которая вернет нам список сотрудников, чьи id не содержатся в первом списке:

SELECT * FROM employee WHERE id NOT IN (1,2,5,4,6)

И результат такого запроса:

id name occupation salary age join_date
3 Иванов Сергей Тестировщик 40000 30 2014-01-01

А теперь можно, как и в предыдущем примере, совместить оба запроса, просто подставив вместо списка id тело первого запроса.

 SELECT * FROM employee WHERE id NOT IN (  SELECT DISTINCT employee_id FROM task  WHERE employee_id IS NOT NULL  )
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Работа с подзапросом
Работа с подзапросом
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Только не Война и Мир
Только не Война и Мир
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Только не Shakespeare
Только не Shakespeare
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Ищем fantasy
Ищем fantasy
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Без null'a но с novel
Без null'a но с novel
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Оператор LIKE
Оператор LIKE
1
Задача
Модуль 4. Работа с БД,  3 уровень,  4 лекция
Недоступна
Операторы LIKE и CONCAT
Операторы LIKE и CONCAT
Комментарии (13)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Алексей
Уровень 115
17 декабря 2025, 18:03
А вот тут Щелкун отщелкался.
Олег
Уровень 106
Expert
19 сентября 2024, 19:57
А вот тут уже сложно
Tony
Уровень 90
14 июня 2025, 16:51
Марат
Уровень 108
Expert
15 декабря 2023, 07:17
Мне не нравится, что когда я смотрю на таблицы, к которым обращаюсь, там совершенно другие значения. Поставьте пожалуйста значения, соответствующие задаче. Так человек хотя бы будет понимать как его запросы работают а не мышечную память тренировать
Эльдар
Уровень 108
Expert
15 августа 2023, 08:22
Несложная тема SQL или просто задачки несложные
The_Red_Baron43
Уровень 31
12 июня 2023, 20:32
О каких задачах идёт речь в обсуждениях под лекциями? У меня никаких задач нет...
Andrey Sautov
Уровень 108
Expert
19 июля 2023, 08:56
вы ещё пожалеете когда увидите этот список задач)))))
Владимир
Уровень 108
24 мая 2023, 14:44
В предпоследней думал будет The Godfather
Артур
Уровень 30
27 апреля 2023, 09:16
Нет смысла делать доступными эти лекции для просмотра без доступа к задачам. Получается смотришь на девку, а действовать не можешь. Как можно научиться, если не делаешь?
darkSide
Уровень 35
3 августа 2023, 21:23
Устанавливаете на свою машину любую популярную субд по типу pg admin 4 или mysql workbench, пишите на коленке таблицы по результатам из лекции и крутите запросы пока не надоест, попутно эксперементируя с запросами.
Anonymous #3322801
Уровень 1
Expert
20 октября 2023, 15:44
Можно хотя бы на образовательном сайте не заниматься объективацией женщин?
Кирилл
Уровень 115
18 июня 2025, 13:49
Вы, наверно, пришли сюда изучить SQL и , возможно, не знаете, что многие здесь после изучения языка Java, а Java, как известно, объектно-ориентированный язык программирования. :-)
aDuVaN4Ik
Уровень 42
3 января 2023, 11:43
Довольно интересная лекция.