Что такое подзапросы
Что проверяют
Владеете ли вы SQL за пределами простых выборок и понимаете ли, во что подзапрос обходится. Для Java-разработчика вопрос прикладной: тот же подзапрос вы пишете в JPQL или собираете через Criteria, и от формы напрямую зависит план.
Как отвечать
Подзапрос это запрос внутри запроса. Классифицируйте его по двум осям.
По месту: в WHERE и HAVING как условие (IN, EXISTS, сравнение со скалярным значением), в FROM как производная таблица, в SELECT как скалярное выражение, вычисляемое на строку.
По связи с внешним запросом: некоррелированный вычисляется один раз и не зависит от строки, коррелированный ссылается на колонки внешнего запроса и логически считается для каждой строки.
SELECT e.id, e.name
FROM employees e
WHERE e.salary > (SELECT avg(salary) FROM employees WHERE dept_id = e.dept_id);Полезное дополнение: EXISTS обычно надёжнее IN на большом подзапросе, повторяющийся подзапрос стоит вынести в CTE, а агрегат по группе часто дешевле посчитать оконной функцией и не обращаться к таблице второй раз.
Где спотыкаются
Пишут NOT IN по подзапросу, в котором встречается NULL, и получают пустой результат. Сравнение с NULL даёт неизвестность, и всё условие перестаёт быть истинным ни для одной строки. NOT EXISTS ведёт себя предсказуемо.
Уверенно заявляют, что подзапрос всегда медленнее соединения. Планировщик обычно разворачивает некоррелированный IN в полусоединение, и разницы не остаётся; коррелированный EXISTS с подходящим индексом бывает быстрее явного JOIN. Судить нужно по плану, а не по форме записи.
Ставят скалярный подзапрос в список выборки и получают отдельное обращение на каждую строку выдачи. В приложении на JPA ровно это выглядит как N+1: цикл по сущностям дёргает ленивую связь, и вместо одного запроса уходит тысяча.