
В SQL вычисление разницы между датами выполняется с помощью специализированных функций, зависящих от СУБД. В MySQL используют функцию DATEDIFF(), которая возвращает количество дней между двумя датами. Например, SELECT DATEDIFF(‘2025-10-10’, ‘2025-10-01’); вернет 9, что позволяет быстро анализировать временные промежутки.
В PostgreSQL для вычисления разницы применяют операцию вычитания дат, результатом которой является тип interval. Запрос SELECT ‘2025-10-10’::date — ‘2025-10-01’::date; вернет 9 days, а для получения количества дней в числовом формате можно использовать EXTRACT(DAY FROM …).
SQL Server предлагает функцию DATEDIFF() с указанием единицы измерения: дни, месяцы, годы. Например, SELECT DATEDIFF(day, ‘2025-10-01’, ‘2025-10-10’); вернет 9. При работе с большими таблицами рекомендуется использовать индексы по колонкам с датами для ускорения вычислений.
Важно учитывать типы данных: DATE, DATETIME и TIMESTAMP могут давать разные результаты при вычислении разницы. Для точных расчетов времени используют функции извлечения компонентов даты, такие как HOUR(), MINUTE(), SECOND() в MySQL или DATE_PART() в PostgreSQL.
Практическая рекомендация – выбирать функции, поддерживаемые конкретной СУБД, и всегда проверять формат данных, чтобы избежать ошибок при вычислениях, особенно если даты содержат временную составляющую. Это позволяет создавать точные отчеты и корректно анализировать временные интервалы в бизнес-логике.
Использование функции DATEDIFF для дней между датами
Функция DATEDIFF в SQL позволяет вычислить количество дней между двумя датами. Синтаксис: DATEDIFF(день, start_date, end_date). Аргумент день указывает, что результат будет выражен в днях, start_date – начальная дата, end_date – конечная.
Пример для MS SQL Server:
SELECT DATEDIFF(day, '2025-01-01', '2025-01-15') AS DaysDifference;
Результат: 14. Функция учитывает разницу календарных дней, включая переход через месяцы и годы.
В MySQL аналогичной функцией является DAYS или TIMESTAMPDIFF:
SELECT TIMESTAMPDIFF(DAY, '2025-01-01', '2025-01-15') AS DaysDifference;
При работе с датами рекомендуется использовать формат 'YYYY-MM-DD' для корректной интерпретации. Для столбцов с типом DATETIME или TIMESTAMP DATEDIFF игнорирует время, учитывая только дату.
Для динамических вычислений между колонками таблицы:
SELECT order_id, DATEDIFF(day, order_date, delivery_date) AS DeliveryDays FROM Orders;
Позволяет быстро определить задержки или продолжительность выполнения операций.
Использование DATEDIFF в условиях WHERE:
SELECT * FROM Events WHERE DATEDIFF(day, event_date, GETDATE()) < 30;
Отбирает записи, где событие произошло менее 30 дней назад.
Важно учитывать отрицательные значения, если start_date позже end_date. Они позволяют корректно оценивать промежутки в обратном порядке.
Вычисление разницы в месяцах с помощью MONTH и YEAR
Для точного подсчета количества месяцев между двумя датами в SQL часто используют комбинацию функций YEAR() и MONTH(). Метод позволяет избежать ошибок округления и корректно учитывает переходы через года.
Базовая формула выглядит так:
(YEAR(дата_конец) - YEAR(дата_начало)) * 12 + (MONTH(дата_конец) - MONTH(дата_начало))
Пример с конкретными датами:
SELECT
(YEAR('2025-10-01') - YEAR('2023-04-15')) * 12
+ (MONTH('2025-10-01') - MONTH('2023-04-15')) AS month_diff;
Результат: 30 месяцев. Формула учитывает полные годы и месяцы, игнорируя дни.
Рекомендации при использовании:
- Если важно учитывать дни для точного округления, можно добавить проверку
DAY()и при необходимости корректировать значение. - Для больших объемов данных рекомендуется использовать индексированные поля, чтобы
YEAR()иMONTH()не снижали производительность. - В MySQL и MariaDB такой подход работает без дополнительной функции, а в SQL Server нужно использовать аналогичные функции
DATEPART(year, дата)иDATEPART(month, дата).
Метод подходит для отчетов, аналитики продаж, расчета абонентских периодов и любых задач, где нужна разница именно в месяцах.
Если хочешь, я могу сделать ещё отдельный блок с примером, где учитываются дни для более точного расчета «почти полного» месяца. Хочешь, чтобы я это сделал?
Разница во времени: часы, минуты и секунды через TIMESTAMPDIFF
Функция TIMESTAMPDIFF позволяет вычислять разницу между двумя датами и временем с точностью до часов, минут или секунд. Синтаксис: TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2), где unit – единица измерения: HOUR, MINUTE, SECOND. Результат – целое число.
Пример расчета разницы в часах между двумя временными метками:
SELECT TIMESTAMPDIFF(HOUR, '2025-10-01 08:30:00', '2025-10-01 17:45:00') AS hours_diff;
Результат: 9 – разница в полных часах между 08:30 и 17:45.
Для вычисления минут используют MINUTE:
SELECT TIMESTAMPDIFF(MINUTE, '2025-10-01 08:30:00', '2025-10-01 17:45:00') AS minutes_diff;
Результат: 555 минут.
Для точного подсчета секунд применяется SECOND:
SELECT TIMESTAMPDIFF(SECOND, '2025-10-01 08:30:00', '2025-10-01 17:45:00') AS seconds_diff;
Результат: 33 300 секунд.
Рекомендации при работе с TIMESTAMPDIFF: используйте единицу измерения, соответствующую требуемой точности. Для длительных интервалов предпочтительнее часы или минуты, для логирования событий – секунды. При отрицательной разнице TIMESTAMPDIFF вернет отрицательное значение, что удобно для проверки порядка дат.
Можно комбинировать TIMESTAMPDIFF с другими функциями, например, DATE_ADD или NOW(), чтобы вычислять интервал относительно текущего времени:
SELECT TIMESTAMPDIFF(MINUTE, NOW(), '2025-10-05 12:00:00') AS minutes_to_event;
Это полезно для расчета оставшегося времени до события.
Сравнение дат с учётом рабочих дней

В SQL стандартные функции для вычисления разницы между датами учитывают все календарные дни. Чтобы рассчитать количество рабочих дней, необходимо исключить выходные и, при необходимости, праздничные дни. Наиболее распространённый подход – использовать пользовательские таблицы с календарём рабочих дней или вычислять через функции.
Пример использования календарной таблицы work_calendar с колонкой is_workday (1 – рабочий день, 0 – выходной):
SELECT COUNT(*) AS workdays_difference
FROM work_calendar
WHERE calendar_date BETWEEN '2025-10-01' AND '2025-10-10'
AND is_workday = 1;
Для баз данных, поддерживающих оконные функции, можно автоматически вычислять рабочие дни без отдельной таблицы:
SELECT SUM(CASE WHEN EXTRACT(DOW FROM date_column) BETWEEN 1 AND 5 THEN 1 ELSE 0 END) AS workdays_count
FROM generate_series('2025-10-01'::date, '2025-10-10'::date, interval '1 day') AS date_column;
Если необходимо учитывать национальные праздники, их список можно хранить в отдельной таблице holidays и вычитать их из подсчёта:
SELECT COUNT(*) AS workdays_difference
FROM work_calendar
LEFT JOIN holidays ON work_calendar.calendar_date = holidays.holiday_date
WHERE calendar_date BETWEEN '2025-10-01' AND '2025-10-10'
AND is_workday = 1
AND holidays.holiday_date IS NULL;
Для наглядного анализа разницы рабочих дней можно использовать таблицу:
| Начальная дата | Конечная дата | Рабочие дни | Выходные | Праздники |
|---|---|---|---|---|
| 2025-10-01 | 2025-10-10 | 7 | 2 | 1 |
В PostgreSQL и Oracle часто применяют функции generate_series и CONNECT BY для создания диапазона дат и последующего фильтра по рабочим дням. В MySQL используют циклы или создают вспомогательную таблицу чисел для аналогичных вычислений. Этот подход обеспечивает точность при расчёте SLA, начисления зарплаты и анализа времени выполнения задач.
Обработка NULL и пустых значений при вычислении интервалов
В SQL при вычислении разницы между датами NULL значения могут приводить к неожиданным результатам. Любая арифметическая операция с NULL возвращает NULL, поэтому `DATEDIFF(end_date, start_date)` вернет NULL, если хотя бы одна из дат отсутствует.
Для корректной обработки используйте функцию `COALESCE`. Например, `DATEDIFF(COALESCE(end_date, CURRENT_DATE), COALESCE(start_date, CURRENT_DATE))` заменяет NULL на текущую дату и позволяет избежать NULL в результате.
Если требуется учитывать только полностью заполненные записи, применяйте фильтр `WHERE start_date IS NOT NULL AND end_date IS NOT NULL`. Это предотвращает попадание пустых дат в вычисления интервалов.
В PostgreSQL альтернативой является функция `AGE`, которая также возвращает NULL при отсутствии одной из дат. Для замены NULL используйте `COALESCE(end_date, start_date)`, чтобы разница была равна нулю при пропущенной дате.
Для массовой обработки таблиц можно создать вычисляемый столбец с защитой от NULL: `ALTER TABLE table_name ADD COLUMN interval_days INT GENERATED ALWAYS AS (COALESCE(DATEDIFF(end_date, start_date), 0)) STORED;`. Это гарантирует, что все вычисленные интервалы будут числовыми.
Пустые строки (») в столбцах типа DATE также вызывают ошибки. Их лучше предварительно конвертировать в NULL с помощью `NULLIF(date_column, »)` перед расчетом разницы.
При суммировании интервалов используйте `SUM(COALESCE(DATEDIFF(end_date, start_date), 0))`, чтобы NULL не обнуляли итоговое значение.
Применение разницы дат в фильтрах и условиях WHERE

В SQL часто необходимо ограничивать выборку данных по времени. Для этого удобно использовать разницу между датами. Например, чтобы выбрать записи, где событие произошло за последние 30 дней, можно применять функцию DATEDIFF:
Пример для SQL Server:
SELECT * FROM Orders WHERE DATEDIFF(day, OrderDate, GETDATE()) <= 30;
Для MySQL аналогично используется функция DATEDIFF, которая возвращает количество дней между двумя датами:
SELECT * FROM Orders WHERE DATEDIFF(CURDATE(), OrderDate) <= 30;
Разница дат также позволяет фильтровать по годам, месяцам или часам. В PostgreSQL для вычисления интервалов используют тип INTERVAL и операторы сравнения:
SELECT * FROM Orders WHERE OrderDate > NOW() - INTERVAL '30 days';
Важно учитывать тип данных: при работе с TIMESTAMP или DATETIME результат функции может включать доли суток. В таких случаях применяют CAST или функции округления для точного сравнения.
Разница дат полезна для фильтров с условием «старше/моложе определенного срока». Например, чтобы выбрать клиентов с активностью более 1 года:
SELECT * FROM Customers WHERE DATEDIFF(year, LastPurchaseDate, GETDATE()) > 1;
При сложных условиях WHERE можно комбинировать разницу дат с логическими операторами. Например, чтобы выбрать заказы, которые были сделаны в пределах 30 дней и сумма которых превышает 1000:
SELECT * FROM Orders WHERE DATEDIFF(day, OrderDate, GETDATE()) <= 30 AND TotalAmount > 1000;
Использование разницы дат в фильтрах повышает точность выборки и позволяет динамически адаптировать запросы под текущую дату, без необходимости вручную менять диапазоны.
Вопрос-ответ:
Как в SQL посчитать количество дней между двумя датами?
В большинстве SQL-систем можно использовать оператор вычитания между датами. Например, в PostgreSQL запись SELECT '2025-10-10'::date - '2025-10-01'::date; вернёт 9, то есть количество дней между указанными датами. В MySQL для этого есть функция DATEDIFF('2025-10-10', '2025-10-01'), которая вернёт аналогичный результат.
Можно ли вычислить разницу между датами в месяцах или годах?
Да, SQL позволяет вычислять разницу не только в днях, но и в месяцах или годах. В PostgreSQL можно использовать функцию AGE: SELECT AGE('2025-10-10', '2023-05-15'); Результат будет в формате интервала, который показывает количество лет, месяцев и дней. В MySQL для месяцев применяют комбинацию функций PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM '2025-10-10'), EXTRACT(YEAR_MONTH FROM '2023-05-15')).
Как учитывать время при вычислении разницы между датами и временем?
Если важны часы, минуты и секунды, нужно использовать типы данных с временной составляющей, например DATETIME или TIMESTAMP. В MySQL можно написать SELECT TIMESTAMPDIFF(SECOND, '2025-10-01 12:00:00', '2025-10-02 14:30:00');, чтобы получить разницу в секундах. В PostgreSQL можно просто вычесть два значения типа TIMESTAMP, и результат будет в виде интервала с точностью до секунд.
Что делать, если даты могут быть в разных форматах?
Перед вычислением разницы важно привести даты к одному формату. В PostgreSQL это делается через приведение к типу DATE или TIMESTAMP, например: SELECT '2025/10/10'::date - '2025-10-01'::date;. В MySQL можно использовать функцию STR_TO_DATE('10/10/2025', '%d/%m/%Y'), чтобы преобразовать строку в дату. После приведения можно выполнять обычные вычисления разницы.
