Вы пишете SELECT u.user_id, (SELECT order_id FROM orders o WHERE o.user_id = u.user_id) AS last_order_id FROM users u. Что может пойти не так и как исправить, чтобы подзапрос стал скалярным?

AЗапрос всегда вернёт случайный order_id, потому что подзапрос выполняется один раз на весь внешний запрос и кэшируется по user_id.
BНужно заменить подзапрос на IN (SELECT order_id ...), иначе внешний SELECT не сможет выполниться и вернёт ошибку синтаксиса.
CНужно добавить DISTINCT во внешний SELECT u.user_id, и тогда подзапрос автоматически станет скалярным и вернёт ровно одно значение.
DЕсли у пользователя несколько заказов, подзапрос вернёт несколько строк и упадёт; нужно гарантировать одно значение через MAX/MIN или LIMIT 1.
Правильный ответ. Скалярный подзапрос в SELECT должен возвращать ровно одну строку и одну колонку для каждой строки внешнего запроса.

Разбор

Если подзапрос потенциально возвращает несколько строк (например, у пользователя несколько заказов), СУБД обычно выдаст ошибку «more than one row returned». Чтобы сделать подзапрос скалярным, нужно явно свести результат к одному значению: агрегатом (MAX/MIN) или ограничением (LIMIT 1 вместе с явным правилом выбора).

Проверь себя · 1/3разбор после ответа
Вы разбираете сложный отчёт коллеги: 4 уровня вложенных подзапросов в FROM без имён шагов. Решаете переписать через WITH. Какое практическое преимущество даёт CTE по сравнению с вложенными подзапросами?
Тренировать SQL в Telegram

Ещё вопросы по теме «Подзапросы и CTE»