Собесов

Где можно использовать скалярные подзапросы

SQLПодзапросыЛёгкаяJunior

Условие

Где можно использовать скалярные подзапросы?

  • В SELECT, FROM, WHERE и HAVING.
  • В SELECT, FROM, WHERE, HAVING, ORDER BY и LIMIT.
  • В SELECT, WHERE и HAVING.
  • В SELECT, FROM, WHERE, HAVING и LIMIT.

Решение

Правильный ответ — в SELECT, FROM, WHERE, HAVING, ORDER BY и LIMIT.

Что такое скалярный подзапрос

Подзапрос, возвращающий ровно одну строку и ровно один столбец — то есть одно значение. Его можно использовать там, где ожидается одно скалярное значение.

Где разрешён

Место Можно? Пример
SELECT (список колонок) Да SELECT id, (SELECT MAX(x) FROM t2) FROM t1
FROM (как «таблица 1×1») Да (необычно) FROM (SELECT MAX(x) AS m FROM t) sub
WHERE Да WHERE id = (SELECT id FROM users WHERE email = ?)
HAVING Да HAVING SUM(x) > (SELECT avg_threshold FROM cfg)
ORDER BY Да ORDER BY (SELECT pos FROM ranks WHERE k = t.k)
LIMIT (PostgreSQL) Да LIMIT (SELECT n FROM cfg)

Что нельзя

  • GROUP BY — нельзя использовать скалярный подзапрос. Группировка должна быть по детерминированным выражениям из FROM.
  • В функциях окна (OVER (...)) — обычно нельзя.

Пример комплексного использования

SELECT
    id,
    name,
    (SELECT AVG(price) FROM products) AS avg_price,
    price - (SELECT AVG(price) FROM products) AS deviation
FROM products
WHERE price > (SELECT AVG(price) FROM products)
HAVING COUNT(*) OVER () > 10
ORDER BY (SELECT 1)  -- редкий, но валидный приём «отключить сортировку»
LIMIT (SELECT page_size FROM settings WHERE key = 'products');

Подводные камни

  1. Скалярный подзапрос вернул > 1 строки = ошибка runtime. Многие СУБД упадут с subquery must return only one row. Защита: LIMIT 1 или агрегат (MAX, MIN).
  2. Скалярный подзапрос в SELECT выполняется на каждую строку. Если в нём нет коррелирующих ссылок, СУБД обычно вычислит один раз и закеширует. Если есть — пересчёт на каждую строку → дорого.
  3. LIMIT (subquery) поддерживает не везде. В PostgreSQL — да, в MySQL до недавнего — нет.

Эталонный ответ

В SELECT, FROM, WHERE, HAVING, ORDER BY и LIMIT. Скалярный подзапрос — это «одно значение», поэтому подходит везде, где ожидается выражение.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти