Функция CAST() в SQL: приведение типов и оператор ::
CAST(значение AS тип) приводит значение к указанному типу данных: текст в число, число в текст, строку в дату. В PostgreSQL есть короткая форма — оператор :: (например, amount::numeric). Для аналитика главный сценарий — защита от целочисленного деления: без приведения 3/2 в SQL даст 1, а не 1.5.
Синтаксис
CAST(значение AS тип) или значение::тип (PostgreSQL)
Примеры использования
Пример 1: Защита от целочисленного деления
SELECT
converted / visitors AS int_div,
CAST(converted AS REAL) / visitors AS correct_ratio
FROM funnel;
Результат:
int_div | correct_ratio
0 | 0.25
Пример 2: Строка-число в число для сортировки
SELECT code, CAST(code AS INTEGER) AS code_num
FROM items
ORDER BY code_num;
Самый частый баг — целочисленное деление: если обе части INTEGER, результат тоже INTEGER и дробь отбрасывается (3/2 = 1). Приводи числитель к REAL/NUMERIC: CAST(a AS REAL) / b. В PostgreSQL деление на ноль всё равно упадёт — оборачивай знаменатель в NULLIF. И помни: CAST текста-не-числа в PostgreSQL это ошибка, в SQLite молчаливый 0/NULL.
Где спрашивают на собеседовании
CAST/:: всплывает в каждой задаче на проценты, конверсию и доли — интервьюер проверяет, помнишь ли ты про целочисленное деление. Идеальная связка для расчёта доли: ROUND(CAST(x AS REAL) / NULLIF(y, 0) * 100, 1).
FAQ: частые вопросы про CAST
Чем отличается CAST от оператора ::?
Это одно и то же приведение типа. CAST(x AS type) — стандарт ANSI, работает везде. Оператор x::type — короткая форма PostgreSQL. В SQLite и MySQL :: нет, используй CAST.
Как избежать целочисленного деления в SQL?
Приведи хотя бы один операнд к дробному типу: CAST(a AS REAL) / b или a::numeric / b. Тогда деление вернёт дробь, а не обрезанное целое.
Что вернёт CAST текста, который не число?
Зависит от СУБД: PostgreSQL выдаст ошибку, SQLite вернёт 0 или NULL. Для безопасного приведения проверяй данные заранее или используй TRY_CAST там, где он есть.