TO_CHAR в SQL — форматирование даты и числа в строку по шаблону

TO_CHAR превращает дату, время или число в текст по заданному шаблону формата: 'YYYY-MM' для группировки по месяцам, 'DD.MM.YYYY HH24:MI' для читаемой метки времени, '999,990.00' для денег с разделителями. Аналитику она нужна каждый раз, когда результат идёт в отчёт или дашборд и важен человекочитаемый вид. Важный нюанс диалектов: TO_CHAR есть в PostgreSQL и Oracle, но её НЕТ в SQLite и MySQL — там используют strftime() и DATE_FORMAT() соответственно.

Синтаксис

TO_CHAR(expression, format_pattern) -- дата/время TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI') -- число TO_CHAR(numeric, 'FM999,990.00')

Примеры использования

Пример 1: Группировка заказов по месяцам

SELECT TO_CHAR(created_at, 'YYYY-MM') AS month,
       COUNT(*) AS orders
FROM orders
GROUP BY 1
ORDER BY 1;

Результат:

month   | orders
--------+-------
2026-01 | 1240
2026-02 | 1388
2026-03 | 1502

Пример 2: Сумма платежа с разделителями

SELECT id,
       TO_CHAR(amount, 'FM9,999,990.00') AS amount_fmt
FROM payments
WHERE status = 'paid'
LIMIT 2;

Результат:

id  | amount_fmt
----+-----------
101 | 12,500.00
102 | 1,990.00

Пример 3: Читаемая дата и время

SELECT TO_CHAR(created_at, 'DD.MM.YYYY HH24:MI') AS ts
FROM orders
ORDER BY created_at DESC
LIMIT 2;

Результат:

ts
-----------------
11.07.2026 14:32
11.07.2026 14:05
Порешать SQL-задачи в тренажёре →

Типичная ошибка

Результат TO_CHAR — строка, поэтому ORDER BY по ней сортирует лексикографически: для хронологии используйте шаблон 'YYYY-MM-DD' или сортируйте по исходной дате. Коды регистрозависимы (MM — месяц, MI — минуты, HH24 — часы 0-23), а префикс FM убирает ведущие пробелы и нули. В SQLite и MySQL функции нет.

Где спрашивают на собеседовании

Спрашивают, когда речь о форматировании отчётов и группировке по периодам; в паре с DATE_TRUNC (усечение до месяца/недели) и EXTRACT (вытащить часть даты числом).

FAQ: частые вопросы про TO_CHAR

Есть ли TO_CHAR в SQLite и MySQL?

Нет. В SQLite для форматирования дат используют strftime('%Y-%m', col), а чисел — printf(). В MySQL для дат это DATE_FORMAT(col, '%Y-%m'), для чисел — FORMAT(). Переносить SQL с TO_CHAR между диалектами напрямую нельзя.

Почему сортировка по TO_CHAR идёт в неправильном порядке?

TO_CHAR возвращает текст, и он сортируется как строка, а не как дата. Формат '01.2026' встанет раньше '02.2025'. Решение — форматировать в 'YYYY-MM-DD' (лексикографический порядок совпадает с хронологическим) либо сортировать по исходному столбцу даты.

Как убрать лишние пробелы и ведущие нули в числе?

Добавьте префикс FM в начало шаблона, например TO_CHAR(amount, 'FM999990.00'). Без FM PostgreSQL резервирует место под максимальную ширину и выравнивает пробелами. FM (fill mode) выдаёт компактную строку без паддинга.

Задачи в тренажёре по теме

Вопросы с собеседований по теме

Смежные темы SQL

Работа с датами · Строковые функции

Другие функции SQL

LAG · date_trunc · EXTRACT · SUBSTR · strftime · CONCAT

Открыть SQL-тренажёр (565 задач) →