我需要获得前几个月的最后一天,包括当月,直到指定月份。例如,我需要9月,8月,7月,6月,5月,3月,3月,2015年1月,2015年12月的最后几天:
temptable_mytable :
last_day_of_month
-----------------
2016-09-30
2016-08-31
2016-07-31
2016-06-30
2016-05-31
2016-04-30
2016-03-31
2016-02-30
2016-01-31
2015-12-31
我需要指定要回溯的月份和年份 - 在上述情况下是2015年12月,但也可能是2015年9月等。有没有办法让我可以做一个循环而不必每个月结束时单独计算?
答案 0 :(得分:3)
使用带有EOMONTH功能的递归CTE。
DECLARE @startdate DATE = '2016-01-01'
;WITH CTE
AS
(
SELECT EOMONTH(GETDATE()) as 'Dates'
UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -1, [Dates]))
FROM CTE WHERE Dates > DATEADD(MONTH, 1, @startdate)
)
SELECT * FROM CTE
答案 1 :(得分:3)
display: inline-block;
答案 2 :(得分:2)
declare @LASTMONTH date = '2018-10-01';
WITH MTHS AS (
SELECT dateadd(month,month(getdate()),dateadd(year,year(getdate()) - 1900, 0)) aday
UNION ALL
SELECT DATEADD(month,1,aday) from MTHS WHERE aday <= @LASTMONTH
),
LASTDAYS AS (SELECT DATEADD(day,-1,aday) finaldayofmonth from MTHS)
select * from LASTDAYS
这是一个适当前进或后退的版本
declare @LASTMONTH date = '2013-10-01';
WITH DIF AS (SELECT CASE WHEN
YEAR(@LASTMONTH) * 12 + MONTH(@LASTMONTH)
>= YEAR(GETDATE()) * 12 + MONTH(getdate()) THEN 1 ELSE -1 END x),
MTHS AS (
SELECT dateadd(month,month(getdate()),dateadd(year,year(getdate()) - 1900, 0)) aday
UNION ALL
SELECT DATEADD(month,(SELECT X from dif),aday) from MTHS
WHERE month(aday) != month(dateadd(month,1,@LASTMONTH)) or YEAR(aday) != YEAR(dateadd(month,1,@LASTMONTH))
),
LASTDAYS AS (SELECT DATEADD(day,-1,aday) finaldayofmonth from MTHS)
select * from LASTDAYS order by finaldayofmonth
答案 3 :(得分:1)
这是一种方法,使用CTE生成递增数字列表,以便我们可以选择并在DATEADD中使用以返回适当的月数。
通常情况下,如果您经常这样做,而不是像CROSS JOIN那样动态生成数字,我建议只创建一个&#34;数字&#34;只保存从1到#34的数字的表格;某些数字足以满足您的需求&#34;
DECLARE @Date DATE = '20151201'
DECLARE @MonthsBackToGo INTEGER
SELECT @MonthsBackToGo = DATEDIFF(mm, @Date, GETDATE()) + 1;
WITH _Numbers AS
(
SELECT TOP (@MonthsBackToGo) ROW_NUMBER() OVER (ORDER BY o.object_id) AS Number
FROM sys.objects o
CROSS JOIN sys.objects o2
)
SELECT EOMONTH(DATEADD(mm, -(Number- 1), GETDATE())) AS last_day_of_month
FROM _Numbers
答案 4 :(得分:1)
无论你为原始桌子或物体返回或前进多远,都应该向外扩展。
SET NOCOUNT ON;
DECLARE @Dates TABLE ( dt DATE)
DECLARE @Start DATE = DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
DECLARE @End DATE = DATEADD(YEAR, 1, @Start)
WHILE @Start <= @End
BEGIN
INSERT INTO @Dates (dt) VALUES (@Start)
SELECT @Start = DATEADD(DAY, 1, @Start)
END
; With x as
(
Select
dt
, ROW_NUMBER() OVER(PARTITION BY DATEPART(YEAR, Dt), DATEPART(MONTH, Dt) ORDER BY Dt Desc) AS rwn
From @Dates
)
Select *
From x
WHERE rwn = 1
ORDER BY Dt
答案 5 :(得分:0)
基于这些部分的几个不同的SO答案,这是快速拼凑在一起的:
DECLARE @startdate datetime, @enddate datetime
set @startdate = '2015-12-01'
set @enddate = getdate()
;WITH T(date)
AS
(
SELECT @startdate
UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE T.date < @enddate
)
SELECT DISTINCT
DATEADD(
day,
-1,
CAST(CAST(YEAR(date) AS varchar) + '-' + CAST(MONTH(date)AS varchar) + '-01' AS DATETIME))
FROM T OPTION (MAXRECURSION 32767);