Функция EOMONTH

Как узнать последний день месяца по заданной дате, например, текущего месяца?

Текущую дату мы можем узнать, используя встроенную функцию current_timestamp:

select current_timestamp;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Чтобы узнать последний день предыдущего месяца, мы можем от текущей даты отнять номер текущего дня месяца, т.е. количество дней, прошедших от начала месяца:

select dateadd(dd, -day(current_timestamp), current_timestamp);
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Тогда для текущего месяца нам потребуется предварительно добавить один месяц к текущей дате:

select dateadd(dd, -day(dateadd(mm, 1, current_timestamp)),
dateadd(mm, 1, current_timestamp));
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Уберем, наконец, из полученного результата компоненту времени:

select cast(
dateadd(dd, -day(dateadd(mm, 1, current_timestamp)), dateadd(mm, 1, current_timestamp))
as date);
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

В SQL Server 2012 появилась функция EOMONTH, которая позволяет сделать то же самое без применения “процедурной” логики:

select cast(
dateadd(dd, -day(dateadd(mm, 1, current_timestamp)),
dateadd(mm, 1, current_timestamp)) as date
) old_way, eomonth(current_timestamp) new_way;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Если вы получаете ошибку при выполнении последнего запроса, значит учебник еще не переехал на версию SQL Server, поддерживающую EOMONTH.

Ну, а для времени, когда я написал этот запрос, результаты, естественно, совпали:

old_waynew_way
2016-07-312016-07-31

Мы уже знаем, что функция EOMONTH имеет аргументом выражение типа даты. Кроме того, функция имеет также второй (необязательный) целочисленный аргумент, представляющий число месяцев, которые, при наличии, будут добавлены к дате, представленной первым аргументом. Например, следующий запрос даст нам последние дни предыдущего, текущего и следующего месяца для даты ‘2016-01-28’:

select eomonth('2016-01-28',-1) prev_month,
                   eomonth('2016-01-28') this_month,
                   eomonth('2016-01-28', 1) next_month;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
prev_monththis_monthnext_month
2015-12-312016-01-312016-02-29