Основы SQL-запросов: вопросы для собеседования (часть 5)
SELECT, FROM, WHERE, ORDER BY, LIMIT — базовый синтаксис SQL, с которого начинается любое собеседование. Кажется простым, но интервьюеры проверяют порядок выполнения клауз, приоритет операторов и понимание DISTINCT. Твёрдое знание основ — фундамент, без которого сложные задачи не решить.
Вопросы 21–25 из 40
21Что произойдёт при выполнении запроса `SELECT product_id, price - cost AS margin FROM products`, если столбцы `price` и `cost` числовые и не содержат `NULL`?
AЗапрос выполнится успешно и вернёт столбец `margin` с разницей между ценой и себестоимостью для каждой строки
BЗапрос вызовет ошибку выполнения, потому что арифметические операции запрещены в `SELECT` без оборачивания в функцию
CЗапрос создаст новый физический столбец `margin` в самой таблице `products` и сохранит туда вычисленные данные навсегда
DЗапрос выполнится, но столбец `margin` будет содержать `NULL` для всех строк независимо от значений в `price` и `cost`
Ответ: В `SELECT` можно использовать арифметические выражения — результат становится вычисляемым столбцом без изменения таблицы.
SQL позволяет использовать арифметику прямо в `SELECT`: `price - cost` вычислит разницу для каждой строки, а `AS margin` даст этому столбцу имя в результате. Вычисляемый столбец существует только в результате запроса и не изменяет структуру таблицы. Если оба столбца числовые и не содержат `NULL`, результат будет числовым. Утверждения про ошибку, изменение схемы таблицы или сплошной `NULL` неверны и противоречат семантике `SELECT`.
Подробный разбор → 22В таблице `support_tickets` поле `resolved_at` равно `NULL`, если тикет ещё не решён. Нужно вывести сначала нерешённые тикеты, а внутри них — по `created_at` по возрастанию (самые старые сверху). Какой `ORDER BY` подойдёт лучше всего?
A`ORDER BY created_at ASC, resolved_at ASC`
B`ORDER BY resolved_at ASC NULLS FIRST, created_at ASC`
C`ORDER BY resolved_at ASC NULLS LAST, created_at ASC`
D`ORDER BY resolved_at DESC NULLS FIRST, created_at ASC`
Ответ: Сначала сортируйте по признаку «решён/не решён» через `NULLS FIRST`, а затем по времени создания для очереди обработки.
Чтобы нерешённые тикеты шли первыми, сортируем по `resolved_at` так, чтобы `NULL` оказался сверху: `resolved_at ASC NULLS FIRST`. Затем добавляем вторичный критерий `created_at ASC`, и среди нерешённых сверху окажутся самые старые. Вариант с `NULLS LAST` уведёт незакрытые тикеты в конец, а сортировка только по `created_at` смешает решённые и нерешённые в одной выдаче.
Подробный разбор → 23В таблице `orders` нужно вывести заказы так, чтобы сначала шли самые дорогие (`amount`), а при одинаковой сумме — более ранние по `created_at` (чтобы вверху был «первый» из одинаковых). Какой `ORDER BY` подходит?
A`ORDER BY amount DESC, created_at ASC`
B`ORDER BY amount ASC, created_at ASC`
C`ORDER BY created_at ASC, amount DESC`
D`ORDER BY amount DESC, created_at DESC`
Ответ: В `ORDER BY` можно задавать приоритет столбцов и направление сортировки для каждого столбца отдельно.
Основной критерий — сумма заказа, поэтому `amount` должен идти первым. «Самые дорогие сверху» означает `amount DESC`. Вторичный критерий применяется только при равном `amount`: «более ранние выше» означает `created_at ASC`. Итог: `ORDER BY amount DESC, created_at ASC`.
Подробный разбор → 24В запросе используется выражение: `SELECT user_id, CASE WHEN age < 18 THEN 'подросток' WHEN age < 30 THEN 'молодой' WHEN age < 50 THEN 'средний' ELSE 'старший' END AS сегмент FROM users`. Пользователю 25 лет — какое значение он получит и почему?
AСегмент получит значение последней истинной ветки `WHEN`, потому что условия проверяются снизу вверх
BСегмент получит значение первой истинной ветки `WHEN`, потому что условия проверяются сверху вниз
CСегмент будет содержать `NULL` для всех строк, если хотя бы одно условие `WHEN` истинно одновременно
DЗапрос вернёт ошибку, потому что несколько условий `WHEN` не могут одновременно быть истинными
Ответ: `CASE WHEN` проверяет условия по порядку сверху вниз и возвращает результат первой истинной ветки.
Выражение `CASE` перебирает ветки `WHEN` последовательно. Для пользователя 25 лет первое условие `age < 18` ложно, второе `age < 30` истинно — он получит значение «молодой». Третье условие даже не проверяется. Этот порядок важен: если бы `age < 50` стояло первым, пользователь попал бы в группу «средний».
Подробный разбор → 25Нужно показать третью страницу каталога товаров: по 20 товаров на страницу, сортировка по цене по возрастанию. Какой запрос корректный?
A`SELECT product_id, price FROM products ORDER BY price ASC LIMIT 20 OFFSET 20`
B`SELECT product_id, price FROM products ORDER BY price DESC LIMIT 20 OFFSET 40`
C`SELECT product_id, price FROM products ORDER BY price ASC LIMIT 20 OFFSET 40`
D`SELECT product_id, price FROM products ORDER BY price ASC LIMIT 20`
Ответ: Для страницы N при размере P используйте `LIMIT P OFFSET (N-1)*P` вместе с явной сортировкой.
Третья страница при размере 20 означает, что нужно пропустить первые 40 строк и взять следующие 20: `LIMIT 20 OFFSET 40`. Так как требуется сортировка по цене по возрастанию, добавляем `ORDER BY price ASC`. Без сортировки страницы не будут стабильными, потому что исходный порядок строк не гарантирован. Сортировка по убыванию или офсет 20 дадут неверный сегмент данных.
Подробный разбор →