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. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x