Вопросы по теме «Основы SQL-запросов»

Проверь себя · 1/3разбор после ответа
В запросе используется выражение: SELECT user_id, CASE WHEN age < 18 THEN 'подросток' WHEN age < 30 THEN 'молодой' WHEN age < 50 THEN 'средний' ELSE 'старший' END AS сегмент FROM users. Пользователю 25 лет — какое значение он получит и почему?

SELECT, FROM, WHERE, ORDER BY, LIMIT — базовый синтаксис SQL, с которого начинается любое собеседование. Кажется простым, но интервьюеры проверяют порядок выполнения клауз, приоритет операторов и понимание DISTINCT. Твёрдое знание основ — фундамент, без которого сложные задачи не решить.

Всего в этом разделе 40 вопросов. Каждый — с правильным ответом и кратким разбором теории. Разбито на 8 частей по 5 вопросов.

Агрегация, GROUP BY и HAVINGДаты и времяEXPLAIN и оптимизацияВыражения и NULLJOIN и операции множествСтроки и приведение типовПодзапросы и CTEОконные функции

Вопросы 15 из 40

1Что сделает запрос `INSERT INTO archive (order_id, amount, status) SELECT order_id, amount, status FROM orders WHERE status = 'completed'`?
AЗапрос вставит в `archive` только те столбцы из `orders`, которые совпадают по имени, без применения фильтра `WHERE`
BЗапрос вызовет ошибку, потому что `INSERT INTO` и `SELECT` нельзя комбинировать в одной инструкции `INSERT INTO ... SELECT`
CЗапрос вставит в `archive` только заказы со статусом `'completed'` из таблицы `orders` в указанные столбцы
DЗапрос скопирует все строки из `orders` в `archive` без применения условия `WHERE status = 'completed'` к источнику
Ответ: `INSERT INTO ... SELECT` копирует результат запроса `SELECT` в указанную таблицу.

Конструкция `INSERT INTO ... SELECT` берёт результат выборки и вставляет его в целевую таблицу. Здесь `SELECT` фильтрует заказы со статусом `'completed'` и выбирает три столбца. Эти строки вставляются в таблицу `archive` в указанные столбцы. Условие `WHERE` применяется к исходным данным, поэтому копируются не все заказы, а только завершённые.

Подробный разбор →
2Что вернёт запрос `SELECT DISTINCT city, country FROM users`, если в таблице есть повторяющиеся пары `city`-`country`?
AВернёт только уникальные пары `city` и `country`, убирая полные дубликаты строк результата
BВернёт все строки без изменений, потому что `DISTINCT` работает только с одним первым столбцом
CВернёт уникальные значения `city`, но соответствующие `country` останутся без какой-либо дедупликации
DУдалит дубли строк из самой таблицы `users` и вернёт оставшиеся записи как итог запроса
Ответ: `DISTINCT` применяется ко всей комбинации столбцов в `SELECT`, а не к одному из них.

`SELECT DISTINCT` убирает из результата полные дубликаты строк — то есть строки, в которых совпадают все перечисленные столбцы. Если указаны `city` и `country`, то дубликатом считается строка с одинаковой парой значений. `DISTINCT` не изменяет саму таблицу — он действует только на результат запроса. Применять его к одному столбцу из нескольких выбранных тоже нельзя: он всегда работает по всему набору столбцов в `SELECT`.

Подробный разбор →
3В таблице заказов поле cancelled_at заполняется только для отменённых заказов, а для активных оно равно `NULL`. Какой фильтр выберет именно активные (не отменённые) заказы?
AФильтр `WHERE cancelled_at IS NULL` оставит активные строки без даты отмены
BФильтр `WHERE cancelled_at = NULL` отберёт строки, где значение поля совпадает с `NULL`
CФильтр `WHERE cancelled_at <> NULL` отберёт строки, где значение поля не равно `NULL`
DФильтр `WHERE cancelled_at IS NOT NULL` оставит отменённые строки с датой отмены
Ответ: Чтобы отобрать строки с пропуском, используйте `IS NULL`, а не сравнение через `=` или `<>`.

Условие `cancelled_at IS NULL` вернёт `TRUE` для строк, где поля даты отмены нет, то есть для активных заказов. Сравнения вида `= NULL` или `<> NULL` всегда возвращают `UNKNOWN`, а не `TRUE`, поэтому такие фильтры дают пустой результат. Фильтр `IS NOT NULL`, наоборот, оставит только отменённые строки.

Подробный разбор →
4В таблице пользователей 1000 строк, у 200 из них поле `email` равно `NULL`. Чем будут отличаться результаты `SELECT COUNT(*) FROM users` и `SELECT COUNT(email) FROM users`?
AОба запроса вернут `1000`: функция `COUNT` подсчитывает все строки таблицы независимо от значений в столбцах
BОба запроса вернут `800`: строки со значением `NULL` пропускаются обеими функциями подсчёта по одинаковому правилу
CПервый вернёт `800` без `NULL`, второй вернёт `1000` как полное число строк таблицы пользователей в выдаче
DПервый вернёт `1000` (число строк), второй вернёт `800`: `COUNT(email)` пропускает строки со значением `NULL`
Ответ: `COUNT(*)` считает все строки, а `COUNT(столбец)` считает только строки, где значение столбца не равно `NULL`.

`COUNT(*)` подсчитывает количество строк в результате независимо от значений в столбцах — для 1000 строк вернёт 1000. `COUNT(email)` подсчитывает только строки, где `email` не равен `NULL` — вернёт 800. Это важное отличие при работе с данными, где есть пропуски: путаница между этими функциями приводит к неверной оценке наполненности столбца.

Подробный разбор →
5В таблице `users` адрес электронной почты хранится в разном регистре: `Anna@mail.ru`, `anna@MAIL.ru` и т.д. Как надёжнее всего найти все записи с конкретным адресом вне зависимости от регистра?
AПрименить `UPPER(email)` в `WHERE` и сравнивать с верхним регистром искомого адреса
BИспользовать `TRIM(email)` в `WHERE` для удаления пробелов и приведения к единому регистру
CПрименить `LOWER(email)` в `WHERE` и сравнивать с нижним регистром искомого адреса
DПеречислить через `OR` все возможные варианты регистра написания искомого адреса
Ответ: Функции `LOWER` и `UPPER` приводят строку к единому регистру и позволяют сравнивать значения без учёта регистра.

Чтобы сравнение не зависело от того, какие буквы заглавные, удобно привести обе стороны к одному регистру: `WHERE LOWER(email) = LOWER('anna@mail.ru')`. Перечисление всех возможных вариантов написания через `OR` ненадёжно: количество комбинаций растёт экспоненциально с длиной строки, легко что-то пропустить. Функция `TRIM` убирает пробелы по краям, но не меняет регистр букв. На больших таблицах для ускорения такого поиска можно создать функциональный индекс по `LOWER(email)`.

Подробный разбор →
12345678

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать SQL в Telegram

Другие темы: SQL

Агрегация, GROUP BY и HAVINGДаты и времяEXPLAIN и оптимизацияВыражения и NULLJOIN и операции множествСтроки и приведение типовПодзапросы и CTEОконные функции