Получить последний день месяца в SQL
Мне нужно получить последний день месяца, указанный в SQL в качестве даты. Если у меня первый день месяца, я могу сделать что-то вроде этого:
DATEADD(DAY, DATEADD(MONTH,'2009-05-01',1), -1)
Но кто-нибудь знает, как обобщить это, чтобы я мог найти последний день месяца для любой данной даты?
24 ответа
Вот моя версия. Никаких манипуляций со строками или приведения не требуется, только один вызов каждого DATEADD
, YEAR
а также MONTH
функции:
DECLARE @test DATETIME
SET @test = GETDATE() -- or any other date
SELECT DATEADD(month, ((YEAR(@test) - 1900) * 12) + MONTH(@test), -1)
С SQL Server 2012 вы можете использовать функцию EOMONTH.
Возвращает последний день месяца, который содержит указанную дату, с необязательным смещением.
Синтаксис
EOMONTH ( start_date [, month_to_add ] )
Как... я могу найти последний день месяца для любой данной даты?
SELECT EOMONTH(@SomeGivenDate)
Вы можете получить дни в дате, используя функцию DAY():
dateadd(day, -1, dateadd(month, 1, dateadd(day, 1 - day(date), date)))
Работает на SQL сервере
Declare @GivenDate datetime
SET @GivenDate = GETDATE()
Select DATEADD(MM,DATEDIFF(MM, 0, @GivenDate),0) --First day of the month
Select DATEADD(MM,DATEDIFF(MM, -1, @GivenDate),-1) --Last day of the month
Для SQL Server 2012 или выше используйте EOMONTH, чтобы получить последнюю дату месяца
SQL-запрос для отображения даты окончания текущего месяца
DECLARE @currentDate DATE = GETDATE()
SELECT EOMONTH (@currentDate) AS CurrentMonthED
SQL-запрос для отображения даты окончания следующего месяца
DECLARE @currentDate DATE = GETDATE()
SELECT EOMONTH (@currentDate, 1 ) AS NextMonthED
Я знаю, что это старый вопрос, но вот еще одно решение, которое работает для меня
SET @dtDate = "your date"
DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0))
И если кто-то ищет другие примеры, вот ссылка http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
Я надеюсь, что это поможет кому-то еще. Stackru Скалы!!!!
На основании заявлений:
SELECT DATEADD(MONTH, 1, @x) -- Add a month to the supplied date @x
а также
SELECT DATEADD(DAY, 0 - DAY(@x), @x) -- Get last day of month previous to the supplied date @x
как насчет добавления месяца к дате @x и последующего извлечения последнего дня месяца, предшествующего этому (т. е. последнего дня месяца предоставленной даты)
DECLARE @x DATE = '20-Feb-2012'
SELECT DAY(DATEADD(DAY, 0 - DAY(DATEADD(MONTH, 1, @x)), DATEADD(MONTH, 1, @x)))
Примечание: это был тест с использованием SQL Server 2008 R2
Просто немного расширите формулу:
dateadd(day, -1,
dateadd(month, 1,
cast(month('5/15/2009') as varchar(2)) +
'/1/' +
cast(year('5/15/2009') as varchar(4)))
WinSQL: я хотел вернуть все записи за последний месяц:
where DATE01 between dateadd(month,-1,dateadd(day,1,dateadd(day,-day(today()),today()))) and dateadd(day,-day(today()),today())
Это делает то же самое:
where month(DATE01) = month(dateadd(month,-1,today())) and year(DATE01) = year(dateadd(month,-1,today()))
Этот запрос также может быть использован.
DECLARE @SelectedDate DATE = GETDATE()
SELECT DATEADD(DAY, - DAY(@SelectedDate), DATEADD(MONTH, 1 , @SelectedDate)) EndOfMonth
Используя SQL Server, вот еще один способ найти последний день месяца:
SELECT DATEADD(MONTH,1,GETDATE())- day(DATEADD(MONTH,1,GETDATE()))
--## Полезные функции даты
ВЫБИРАТЬ
GETDATE() AS [DateTime],
CAST(GETDATE() AS DATE) AS [Date],
DAY(GETDATE()) AS [Day of Month],
FORMAT(GETDATE(),'MMMM') AS [Month Name],
FORMAT(GETDATE(),'MMM') AS [Month Short Name],
FORMAT(GETDATE(),'MM') AS [Month No],
YEAR(GETDATE()) AS [Year],
CAST(DATEADD(DD,-(DAY(GETDATE())-1),GETDATE()) AS DATE) AS [Month Start Date],
EOMONTH(GETDATE()) AS [Month End Date],
CAST(DATEADD(M,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month Start Date],
CAST(DATEADD(S,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month End Date],
CAST(DATEADD(M,+1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Next Month Start Date],
CAST(DATEADD(D,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE())+2,0)) AS DATE) AS [Next Month End Date],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),0) AS DATE) AS [First Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,-1) AS DATE) AS [Last Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())-1,0) AS DATE) AS [First Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),-1) AS DATE) AS [Last Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,0) AS DATE) AS [First Day of Next Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+2,-1) AS DATE) AS [Last Day of Next Week]
Это работает для меня, используя Microsoft SQL Server 2005:
DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'2009-05-01')+1,0))
WinSQL, чтобы получить последний день прошлого месяца (т.е. сегодня 2017-02-09, возвращает 2017-01-31: выберите dateadd(день,-день (сегодня ()), сегодня ())
Попробуйте выполнить следующий запрос, он даст вам все, что вы хотите:)
Declare @a date =dateadd(mm, Datediff(mm,0,getdate()),0)
Print('First day of Current Month:')
Print(@a)
Print('')
set @a = dateadd(mm, Datediff(mm,0,getdate())+1,-1)
Print('Last day of Current Month:')
Print(@a)
Print('')
Print('First day of Last Month:')
set @a = dateadd(mm, Datediff(mm,0,getdate())-1,0)
Print(@a)
Print('')
Print('Last day of Last Month:')
set @a = dateadd(mm, Datediff(mm,0,getdate()),-1)
Print(@a)
Print('')
Print('First day of Current Week:')
set @a = dateadd(ww, Datediff(ww,0,getdate()),0)
Print(@a)
Print('')
Print('Last day of Current Week:')
set @a = dateadd(ww, Datediff(ww,0,getdate())+1,-1)
Print(@a)
Print('')
Print('First day of Last Week:')
set @a = dateadd(ww, Datediff(ww,0,getdate())-1,0)
Print(@a)
Print('')
Print('Last day of Last Week:')
set @a = dateadd(ww, Datediff(ww,0,getdate()),-1)
Print(@a)
Мои 2 цента:
select DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(day,(0-(DATEPART(dd,'2008-02-12')-1)),'2008-02-12')))
Радж
Если вам это нужно часто, оберните его во встроенный TVF, что очень быстро:
Используя SQL Server 2005, это работает для меня:
select dateadd(dd,-1,dateadd(mm,datediff(mm,0,YOUR_DATE)+1,0))
Как правило, вы получаете количество месяцев с начала (SQL Server) времени для YOUR_DATE. Затем добавьте один к нему, чтобы получить порядковый номер следующего месяца. Затем вы добавляете это число месяцев к 0, чтобы получить дату, которая является первым днем следующего месяца. Из этого вы затем вычитаете день, чтобы добраться до последнего дня YOUR_DATE.
Возьмите некоторую базовую дату, которая является 31-го числа некоторого месяца, например "20011231". Затем используйте
следующая процедура (я привел 3 одинаковых примера ниже, отличается только значение @dt).
declare @dt datetime;
set @dt = '20140312'
SELECT DATEADD(month, DATEDIFF(month, '20011231', @dt), '20011231');
set @dt = '20140208'
SELECT DATEADD(month, DATEDIFF(month, '20011231', @dt), '20011231');
set @dt = '20140405'
SELECT DATEADD(month, DATEDIFF(month, '20011231', @dt), '20011231');
Я не смог найти ответ, который работал бы в обычном SQL, поэтому я переборщил ответ:
SELECT *
FROM orders o
WHERE (MONTH(o.OrderDate) IN ('01','03','05','07','08','10','12') AND DAY(o.OrderDate) = '31')
OR (MONTH(o.OrderDate) IN ('04','06','09','11') AND DAY(o.OrderDate) = '30')
OR (MONTH(o.OrderDate) IN ('02') AND DAY(o.OrderDate) = '28')
Я написал следующую функцию, она работает.
Возвращает тип данных datetime. Ноль часа, минуты, секунды, миллисекунды.
CREATE Function [dbo].[fn_GetLastDate]
(
@date datetime
)
returns datetime
as
begin
declare @result datetime
select @result = CHOOSE(month(@date),
DATEADD(DAY, 31 -day(@date), @date),
IIF(YEAR(@date) % 4 = 0, DATEADD(DAY, 29 -day(@date), @date), DATEADD(DAY, 28 -day(@date), @date)),
DATEADD(DAY, 31 -day(@date), @date) ,
DATEADD(DAY, 30 -day(@date), @date),
DATEADD(DAY, 31 -day(@date), @date),
DATEADD(DAY, 30 -day(@date), @date),
DATEADD(DAY, 31 -day(@date), @date),
DATEADD(DAY, 31 -day(@date), @date),
DATEADD(DAY, 30 -day(@date), @date),
DATEADD(DAY, 31 -day(@date), @date),
DATEADD(DAY, 30 -day(@date), @date),
DATEADD(DAY, 31 -day(@date), @date))
return convert(date, @result)
end
Это очень просто в использовании. 2 пример:
select [dbo].[fn_GetLastDate]('2016-02-03 12:34:12')
select [dbo].[fn_GetLastDate](GETDATE())
Основываясь на ответе, получившем наибольшее количество голосов по ссылке ниже, я придумал следующее решение:
declare @mydate date= '2020-11-09';
SELECT DATEADD(month, DATEDIFF(month, 0, @mydate)+1, -1) AS lastOfMonth
---Start/End of previous Month
Declare @StartDate datetime, @EndDate datetime
set @StartDate = DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0)
set @EndDate = EOMONTH (DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0))
SELECT @StartDate,@EndDate
Функция LAST_DAY прекрасно работает для этого.
Изменить: На самом деле, как упоминалось в комментариях, это, вероятно, не для всех SQL. Я оставлю пост на случай, если кто-то ищет ответ MySQL/Oracle, наткнувшись на него.
Из справочного руководства по mysql:
LAST_DAY(date)
Принимает значение даты или даты и времени и возвращает соответствующее значение для последнего дня месяца. Возвращает NULL, если аргумент неверен.
mysql> SELECT LAST_DAY('2003-02-05');
-> '2003-02-28'
mysql> SELECT LAST_DAY('2004-02-05');
-> '2004-02-29'
mysql> SELECT LAST_DAY('2004-01-01 01:01:01');
-> '2004-01-31'
mysql> SELECT LAST_DAY('2003-03-32');
-> NULL
LAST_DAY () доступен с MySQL 4.1.1.