Как рассчитать последний день месяца в SQL? - PullRequest
6 голосов
/ 08 октября 2008

В частности, MSSQL 2005.

Ответы [ 9 ]

17 голосов
/ 08 октября 2008

Вот решение, которое дает вам последнюю секунду текущего месяца. Вы можете извлечь часть даты или изменить ее, чтобы вернуть только день. Я проверял это на SQL Server 2005.

select dateadd( s, -1, dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 ) );

Чтобы понять, как это работает, мы должны взглянуть на функции dateadd () и datediff () .

DATEADD(datepart, number, date)  
DATEDIFF(datepart, startdate, enddate)

Если вы выполните только самый внутренний вызов функции datediff (), вы получите номер текущего месяца с отметкой времени 0.

select datediff(m, 0, getdate() );  
1327

Следующая часть добавляет это число месяцев плюс 1 к отметке времени 0, давая вам начальную точку следующего календарного месяца.

select dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 );
2010-09-01 00:00:00.000

Наконец, внешний метод dateadd () просто вычитает одну секунду из начальной отметки времени следующего месяца, давая вам последнюю секунду текущего месяца.

select dateadd( s, -1, dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 ) );
2010-08-31 23:59:59.000

<ч /> Этот старый ответ (ниже) содержит ошибку, из-за которой он не работает в последний день месяца, в котором больше дней, чем в следующем месяце. Я оставляю это здесь как предупреждение для других.

Добавьте один месяц к текущей дате, а затем вычтите значение, возвращенное функцией DAY, примененной к текущей дате, используя функции DAY и DATEADD.

dateadd(day, -day(getdate()), dateadd(month, 1, getdate()))
4 голосов
/ 08 октября 2008
SELECT DATEADD(M, DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), '1990-01-31T00:00:00.000')

Объяснение:

Общий подход: использовать временную функциональность.

SELECT '1990-01-01T00:00:00.000', '1990-01-31T00:00:00.000'

Это литералы DATETIME, являющиеся гранулой первого раза в первый и последний день соответственно одного и того же 31-дневного месяца. Какой месяц выбран, совершенно произвольно.

SELECT DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP)

Это разница в полных месяцах между первым днем ​​отчетного месяца и текущей отметкой времени. Давайте назовем это @calc.

SELECT DATEADD(M, @calc, '1990-01-31T00:00:00.000')

Это добавляет @calc гранулы месяца к последнему дню отчетного месяца, результатом которого является текущая метка времени, округленная до последнего дня его месяца. Q.E. D.

3 голосов
/ 08 октября 2008

Попробуйте это:

DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, CURRENT_TIMESTAMP) + 1, 0)
2 голосов
/ 07 июля 2011

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

Ниже приведен пошаговый способ написания запроса:

В SQL Server Дата начинается с 1901/01/01 (дата 0) и по сей день каждый месяц можно идентифицировать по номеру. 12-й месяц первый месяц 1902 года означает январь. Месяц 1200 - январь 2001 года. Аналогичным образом каждому дню можно присвоить уникальный номер, например, дата 0 - 1901/01/01. Дата 31 - 1901/02/01, а январь 1901 года начинается с 0.

Чтобы узнать первый день текущего месяца (текущая дата или заданная дата)

  1. Сначала нам нужно проверить, сколько месяцев прошло с даты 0 (1901/01/01). ВЫБЕРИТЕ DATEDIFF (MM, 0, GETDATE ())
  2. Добавить то же число месяца к дате 0 (1901/01/01)

    ВЫБРАТЬ ДАТУЮ ДАТУ (MM, DATEDIFF (MM, 0, GETDATE ()), 0)

Тогда мы получим первый день текущего месяца (текущая дата или заданная дата)

Чтобы получить последний день прошлого месяца

Нам нужно вычесть секунду из первого дня текущего месяца

SELECT DATEADD (SS, -1, DATEADD (MM, DATEDIFF (MM, 0, GETDATE ()), 0))

Чтобы получить последний день текущего месяца

Чтобы получить первый день текущего месяца, сначала мы проверили, сколько месяцев прошло с даты 0 (1901/01/01). Если мы добавим еще один месяц с общим количеством месяцев с даты 0, а затем добавим общее количество месяцев с датой 0, мы получим первый день следующего месяца.

SELECT DATEADD(MM, DATEDIFF(MM,0,GETDATE())+1,0)

Если мы получим первый день следующего месяца, а затем последний день текущего месяца, все, что нам нужно вычесть секунду.

SELECT DATEADD (SS, -1, DATEADD (MM, DATEDIFF (MM, 0, GETDATE ()) + 1,0))

Надеюсь, это поможет.

1 голос
/ 02 ноября 2015

Используя SQL2005, у вас нет доступа к полезной функции EOMONTH(), поэтому вы должны рассчитать это самостоятельно.

Эта простая функция будет работать аналогично EOMONTH

CREATE FUNCTION dbo.endofmonth(@date DATETIME= NULL)
RETURNS DATETIME
BEGIN
RETURN DATEADD(DD, -1, DATEADD(MM, +1, DATEADD(DD, 1 - DATEPART(DD, ISNULL(@date,GETDATE())), ISNULL(@date,GETDATE()))))
END

Запрос на выполнение:

SELECT dbo.endofmonth(DEFAULT)  --Current month-end date
SELECT dbo.endofmonth('02/25/2012') --User-defined month-end date
0 голосов
/ 21 сентября 2009
DATEADD(dd, -1, DATEADD(mm, +1, DATEADD(dd, 1 - DATEPART(dd, @myDate), @myDate)))
0 голосов
/ 08 октября 2008

Для полноты, в Oracle вы бы сделали что-то вроде ...

select add_months(trunc(sysdate,'MM'),1) ...

или

select last_day(sysdate)+1 ...
0 голосов
/ 08 октября 2008
DECLARE
  @Now datetime,
  @Today datetime,
  @ThisMonth datetime,
  @NextMonth datetime,
  @LastDayThisMonth datetime

SET @Now = getdate()
SET @Today = DateAdd(dd, DateDiff(dd, 0, @Now), 0)
SET @ThisMonth = DateAdd(mm, DateDiff(mm, 0, @Now), 0)
SET @NextMonth = DateAdd(mm, 1, @ThisMonth)
SET @LastDayThisMonth = DateAdd(dd, -1, @NextMonth)

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

WHERE @ThisMonth <= someDate and someDate < @NextMonth
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...