Найти тему
ERP админ

3 распространённых способа присвоить переменной последнюю дату месяца одной командой

Оглавление

В финансовых отчётах, отчётах по продажам и других, в качестве фильтра часто используется последняя дата текущего месяца. Хорошо бы эту дату подставлять, при вводе параметров, автоматически, чтобы пользователь вводил только значимые для него параметры. К сожалению в MS SQL такая функция отсутствует, поэтому я получал даты последнего дня месяца разными способами.
По мере изучения SQL я пользовался тремя различными способами.

Самый первый способ


Без использования функций обработки даты. Заключается в том, что последняя дата месяца легко прогнозируемая величина, зависит от месяца, и для февраля, от того является ли год високосным. В результате получилась такая команда:

CONVERT(datetime, CAST(YEAR(GETDATE()) as nchar(4)) + right('00' + cast(month(GETDATE()) as nvarchar(2)),2) +
case
when MONTH(GETDATE()) in (1,3,5,7,8,10,12) then '31'
when MONTH(GETDATE()) in (4,6,9,11) then '30'
when MONTH(GETDATE()) = 2 and year(GETDATE()) % 4 = 0 then '29'
else '28'
end, 112)

Более универсальный способ


По мере изучения функции DATEADD несколько упростил вариант:

DATEADD(hh, -1, DATEADD(m,1,
convert(datetime, cast(year(GETDATE()) as nchar(4)) +
right('00' + cast(month(GETDATE()) as nvarchar(2)),2) + '01', 112)))

Третий, самый короткий

К используемым способам добавил вычисление месяца от нулевой даты, воспользовавшись функцией DATEDIFF:

DATEADD(d, -1, DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))

С какой точностью можно получить даты?

Во втором и третьем способе, меняя параметр периода DATEADD(d, -1, ... , можно получить точность начиная от миллисекунды (период ms) до дня (d).


ms 2023-02-23 2023-02-28 23:59:59.997
s 2023-02-23 2023-02-28 23:59:59.000
mi 2023-02-23 2023-02-28 23:59:00.000
hh 2023-02-23 2023-02-28 23:00:00.000
d 2023-02-23 2023-02-28 00:00:00.000

При периоде - миллисекунда, можно получить только .997 при значении -2, используя значение -1, получаем первый день следующего месяца. Скорее всего это связано с точностью полученного числа.

Вместо заключения

С точки зрения нагрузки на sql сервер, судя по планам выполнения, все три способа потребляют одинаковое количество ресурсов. Поэтому можно использовать любой, в зависимости от той задачи, которая стоит перед вами.
Если вы пользуетесь другими способами.
Расскажите пожалуйста об этом в комментариях!