SQL
Как вытащить месяц из даты в SQL: MONTH, EXTRACT и strftime
Месяц из даты в SQL достают функцией, которая зависит от базы данных. В SQL Server и MySQL часто используют MONTH(date_column), в PostgreSQL — EXTRACT(MONTH FROM date_column), в SQLite — strftime('%m', date_column)
Если вы строите отчет, почти всегда нужно вытаскивать не только месяц, но и год. Иначе январь 2025 и январь 2026 попадут в одну группу, а отчет станет неверным
SQL Server
SELECT
order_id,
created_at,
YEAR(created_at) AS order_year,
MONTH(created_at) AS order_month
FROM orders;
Если нужно сгруппировать продажи по месяцу:
SELECT
YEAR(created_at) AS order_year,
MONTH(created_at) AS order_month,
SUM(total_sum) AS total_sales
FROM orders
GROUP BY YEAR(created_at), MONTH(created_at)
ORDER BY order_year, order_month;
Так отчет не смешает одинаковые месяцы разных лет
PostgreSQL
SELECT
order_id,
created_at,
EXTRACT(YEAR FROM created_at) AS order_year,
EXTRACT(MONTH FROM created_at) AS order_month
FROM orders;
Для группировки:
SELECT
date_trunc('month', created_at) AS month_start,
SUM(total_sum) AS total_sales
FROM orders
GROUP BY date_trunc('month', created_at)
ORDER BY month_start;
date_trunc('month', ...) часто удобнее, потому что дает начало месяца как дату, а не отдельные числа года и месяца
MySQL
SELECT
order_id,
created_at,
YEAR(created_at) AS order_year,
MONTH(created_at) AS order_month
FROM orders;
Для красивого периода можно использовать форматирование:
SELECT
DATE_FORMAT(created_at, '%Y-%m') AS order_month,
SUM(total_sum) AS total_sales
FROM orders
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
ORDER BY order_month;
SQLite
SELECT
order_id,
created_at,
strftime('%Y', created_at) AS order_year,
strftime('%m', created_at) AS order_month
FROM orders;
В SQLite результат strftime возвращается как текст. Для отчетов это нормально, но для числовых сравнений может понадобиться преобразование
Мини-практика
Создайте учебную таблицу:
CREATE TABLE orders_demo (
id int IDENTITY(1,1) PRIMARY KEY,
created_at date NOT NULL,
total_sum decimal(10,2) NOT NULL
);
INSERT INTO orders_demo (created_at, total_sum)
VALUES
('2026-01-10', 1000),
('2026-01-20', 1500),
('2026-02-05', 900);
Сгруппируйте продажи по году и месяцу:
SELECT
YEAR(created_at) AS order_year,
MONTH(created_at) AS order_month,
SUM(total_sum) AS total_sales
FROM orders_demo
GROUP BY YEAR(created_at), MONTH(created_at)
ORDER BY order_year, order_month;
Ожидаемый результат:
| 2026 | 1 | 2500.00 |
|---|---|---|
| 2026 | 2 | 900.00 |
Частые ошибки
- Группируют только по месяцу и смешивают разные годы
- Копируют
MONTH()в PostgreSQL, где обычно нуженEXTRACT - Форматируют дату в текст слишком рано, а потом не могут правильно сортировать
- Не учитывают
NULLв дате - Путают номер месяца и название месяца
- Фильтруют по функции от даты и теряют пользу индекса
Что почитать дальше по SQL
Если нужен общий маршрут по теме, откройте рубрику SQL. Для соседних задач пригодятся эти разборы:
- ALTER TABLE в SQL: как добавить, изменить и удалить столбец
- BETWEEN SQL: как выбрать значения в диапазоне
- CREATE TABLE SQL: как создать таблицу запросом
- CSV в SQL: как загрузить файл в базу данных