Условие
Где можно использовать скалярные подзапросы?
- В
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 строки = ошибка runtime. Многие СУБД упадут с
subquery must return only one row. Защита:LIMIT 1или агрегат (MAX,MIN). - Скалярный подзапрос в
SELECTвыполняется на каждую строку. Если в нём нет коррелирующих ссылок, СУБД обычно вычислит один раз и закеширует. Если есть — пересчёт на каждую строку → дорого. LIMIT (subquery)поддерживает не везде. В PostgreSQL — да, в MySQL до недавнего — нет.
Эталонный ответ
В SELECT, FROM, WHERE, HAVING, ORDER BY и LIMIT. Скалярный подзапрос — это «одно значение», поэтому подходит везде, где ожидается выражение.