Строки и приведение типов: вопросы для собеседования (часть 4)
LIKE, SUBSTRING, CONCAT, TRIM, CAST, регулярные выражения — строковые функции нужны для парсинга и очистки данных. На собеседовании могут попросить извлечь домен из email, привести строку к числу или разобрать URL. Эти задачи проверяют практический опыт работы с «грязными» данными.
Вопросы 16–20 из 20
16В таблице `customers` поле `lifetime_value_text` хранится как текст. Вы делаете топ клиентов по выручке, но сортировка выглядит неверно (например, `100` идёт раньше `20`). Как исправить `ORDER BY`?
AСортировать по приведённому числу: `ORDER BY CAST(lifetime_value_text AS int) DESC`.
BСортировать по длине строки: `ORDER BY LENGTH(lifetime_value_text) DESC`.
CСортировать по `LOWER(lifetime_value_text)`.
DДобавить `TRIM` без каста: `ORDER BY TRIM(lifetime_value_text) DESC`.
Ответ: Текстовая сортировка и числовая сортировка отличаются; для чисел нужен каст.
Когда значение хранится текстом, `ORDER BY` сравнивает строки, а не числа, поэтому порядок может быть неожиданным. Явное приведение к числовому типу через `CAST(... AS int)` (или другой подходящий тип) делает сортировку корректной для аналитического смысла.
17В `amount_text` суммы записаны как текст, но иногда встречается пустая строка `''`. Запрос `SUM(CAST(amount_text AS int))` падает. Какое выражение чаще всего решает проблему, превращая пустые строки в `NULL` перед кастом?
A`SUM(amount_text)`
B`SUM(CAST(NULLIF(TRIM(amount_text), '') AS int))`
C`SUM(TRIM(amount_text))`
D`SUM(LOWER(amount_text))`
Ответ: Перед кастом удобно превращать пустые строки в `NULL` через `NULLIF` и убирать пробелы через `TRIM`.
Каст `CAST('' AS int)` обычно приводит к ошибке. Частый паттерн для аналитики — сначала очистить значение `TRIM(...)`, затем заменить пустую строку на `NULL` через `NULLIF(..., '')`, и только потом приводить тип. Так агрегации вроде `SUM(...)` становятся устойчивее к «грязным» данным.
18В `discount_text` скидка хранится как текст, но иногда значение отсутствует и записано как `''` или `' '`. Вы хотите получить `discount_int`, где пропуски становятся `NULL`, и не ловить ошибку каста. Какое выражение лучше всего подходит?
A`CAST(discount_text AS int)`
B`TRIM(discount_text)::int`
C`CAST(NULLIF(TRIM(discount_text), '') AS int)`
D`LOWER(discount_text)::int`
Ответ: Паттерн `CAST(NULLIF(TRIM(x), '') AS int)` часто используют для устойчивого каста текста в число.
Пустые строки и строки из пробелов — частый «заменитель NULL» в сырых данных. `TRIM` убирает пробелы по краям, `NULLIF(..., '')` превращает пустую строку в `NULL`, а затем каст уже безопаснее. Это снижает количество падений запросов при агрегациях и витринах.
19В `orders.user_id` тип `int`, а в `web_events.user_id_text` тип `text` (значения выглядят как `42`). Какой вариант условия в `JOIN` обычно лучше отражает числовой смысл идентификатора?
A`orders.user_id = web_events.user_id_text`
B`orders.user_id::text = web_events.user_id_text`
C`orders.user_id = CAST(web_events.user_id_text AS int)`
D`LOWER(orders.user_id) = LOWER(web_events.user_id_text)`
Ответ: Лучше явно приводить типы к одному смысловому типу, а не полагаться на неочевидные сравнения.
Если идентификатор по смыслу числовой, то сравнение в числовом типе обычно понятнее и уменьшает риск странных несовпадений. Каст текстового значения через `CAST(... AS int)` делает намерение явным. При этом важно, чтобы данные были чистыми (например, без `''` и букв), иначе каст может падать.
20Вы объединяете два источника событий через `UNION ALL`: в одном `user_id` имеет тип `int`, в другом `user_id_text` имеет тип `text` (значения выглядят как `42` и могут содержать пробелы). Дальше вы делаете `JOIN` к `users.id` (тип `int`). Что надежнее сделать, чтобы избежать ошибок типов и неожиданных сравнений?
AНичего не делать: типы в `UNION ALL` всегда сохраняются «как есть».
BПривести `users.id` к `text` в финальном `JOIN`: `users.id::text = events.user_id`.
CСделать `LOWER(user_id_text)` перед `UNION ALL`, чтобы тип стал совместимым.
DЯвно привести тип в обоих селектах до объединения, например `SELECT user_id AS user_id ... UNION ALL SELECT CAST(TRIM(user_id_text) AS int) AS user_id ...`.
Ответ: В объединениях и последующих `JOIN` лучше заранее привести ключи к одному типу явным образом.
Когда источники имеют разные типы, неявные приведения могут приводить к ошибкам, неожиданным результатам или лишним преобразованиям на каждом шаге. Приведение ключа к `int` до `UNION ALL` делает тип итоговой колонки контролируемым и понятным, а `TRIM` помогает убрать простой «мусор» вроде пробелов. Это снижает риск багов в дальнейших соединениях и фильтрах.
Хотите тренировать интерактивно?
В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.
Тренировать в Telegram