Вопросы по теме «Строки и приведение типов»

Проверь себя · 1/3разбор после ответа
В таблице products код товара хранится как текст, например 00123 (важны ведущие нули). Вы хотите соединить её с catalog(code) (тоже текст). Какое действие чаще всего приводит к багу и пропущенным совпадениям?

LIKE, SUBSTRING, CONCAT, TRIM, CAST, регулярные выражения — строковые функции нужны для парсинга и очистки данных. На собеседовании могут попросить извлечь домен из email, привести строку к числу или разобрать URL. Эти задачи проверяют практический опыт работы с «грязными» данными.

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

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

Вопросы 15 из 20

1В `product_category` иногда попадают хвостовые пробелы. В отчёте по категориям вы хотите убрать дубли групп, но менять исходные данные нельзя. Что лучше сделать в запросе?
AДобавить `LIMIT 100` в конец запроса, чтобы дублирующиеся группы просто не попадали в видимую часть отчёта
BГруппировать по очищенному значению: `GROUP BY TRIM(product_category)`, и в `SELECT` использовать тот же `TRIM(product_category)`
CПривести категорию к числу через `product_category::int`, чтобы пробелы автоматически отбрасывались при приведении типа
DСделать `ORDER BY TRIM(product_category)` без `GROUP BY`, чтобы похожие значения хотя бы стояли рядом в выдаче
Ответ: Если группировка «размножается» из-за пробелов, нормализация выражения в `SELECT` и `GROUP BY` решает проблему.

Группировка считает строки разными, если символы отличаются, даже когда различие только в пробеле. `TRIM(product_category)` приводит значения к одному виду и склеивает дубликаты групп. Важно использовать одинаковое выражение и в `SELECT`, и в `GROUP BY`, чтобы результат был согласованным. `LIMIT` лишь прячет проблему, приведение к числу сломается на текстовых значениях, а `ORDER BY` без `GROUP BY` оставит все дубли в выдаче.

Подробный разбор →
2Вы строите ключ сессии как склейку `user_id` (тип `int`) и `session_id` (тип `text`). Какой вариант корректен для конкатенации в SQL?
A`user_id || '-' || session_id`
B`CAST(user_id AS int) || '-' || session_id`
C`user_id + '-' || session_id`
D`user_id::text || '-' || session_id`
Ответ: Для конкатенации строк числовые поля приводят к тексту через `CAST` или `::text`.

Оператор `||` в SQL работает со строками. Если один из операндов — число, его нужно явно привести к тексту: `user_id::text` или `CAST(user_id AS text)`. Это предотвращает ошибки типов и делает намерение запроса ясным. Вариант с `+` неверен: в большинстве СУБД `+` для строк не работает, а в SQL Server он не сможет сложить число и текст.

Подробный разбор →
3В таблице `products` категория хранится как `Books`, `books`, `BOOKS`. Нужно одним условием в `WHERE` отобрать все варианты категории «книги». Какой фильтр наиболее надёжен?
A`WHERE category = 'Books'`
B`WHERE category = LOWER('Books')`
C`WHERE LOWER(category) = 'books'`
D`WHERE UPPER(category) = 'Books'`
Ответ: Чтобы фильтр не зависел от регистра, обе стороны сравнения приводят к одному регистру через `LOWER` или `UPPER`.

Если данные приходят из разных источников, регистр часто «гуляет». Условие `LOWER(category) = 'books'` приводит значения к единому виду перед сравнением и ловит все варианты написания. Сравнение с `LOWER('Books')` приводит только литерал, а не сам столбец, поэтому ничем не помогает. Вариант `UPPER(category) = 'Books'` ломается из-за смешанного регистра справа, а прямое сравнение с `'Books'` пропускает большинство строк.

Подробный разбор →
4В поле `full_name` встречаются значения вроде `'Ivan'` и `'ivan '` (с пробелом в конце). Нужно надёжно отфильтровать всех пользователей с именем «ivan» независимо от регистра и пробелов по краям. Какое условие подходит лучше всего?
A`full_name = 'ivan'`
B`TRIM(full_name) = 'Ivan'`
C`TRIM(LOWER(full_name)) = 'ivan'`
D`LOWER(full_name) = 'ivan'`
Ответ: Комбинация `TRIM` и `LOWER` делает сравнение устойчивым к лишним пробелам и разному регистру в текстовых данных.

В реальных данных часто встречаются лишние пробелы и разные варианты регистра. Если сравнивать «как есть» через `full_name = 'ivan'`, вы получите пропуски. Приведение к единому регистру через `LOWER` и удаление пробелов через `TRIM` дают стабильное условие. Только `LOWER` без `TRIM` пропустит значение `'ivan '`, а `TRIM` без `LOWER` оставит `'Ivan'` за рамками выборки.

Подробный разбор →
5В `users.phone` иногда попадают значения с ведущими/хвостовыми пробелами. Вы фильтруете `WHERE phone = '+79991234567'`, но часть пользователей не находится. Как исправить фильтр?
A`WHERE LOWER(phone) = '+79991234567'`
B`WHERE CAST(phone AS int) = 79991234567`
C`WHERE SUBSTRING(phone, 1, 3) = '+79'`
D`WHERE TRIM(phone) = '+79991234567'`
Ответ: Лишние пробелы ломают сравнение строк; `TRIM` часто решает проблему.

Даже один пробел делает строку другой, поэтому равенство в `WHERE` перестаёт совпадать. `TRIM(phone)` убирает пробелы в начале и конце, сохраняя остальную строку. Это простая и частая чистка для полей вроде телефонов и категорий.

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

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

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

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

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

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