我有以下情况。我需要2013年至今的任何一个月的最后几天。
如何组合这两个sql语句?
SELECT DATEADD(m, 0, GETDATE()) --today
SELECT DATEDIFF(m, '2013-01-01', GETDATE()) --60 months for 5 years
我需要这个结果:
LastDayOfMth
=======================
2013-01-31 00:00:00.000
2013-02-28 00:00:00.000
2013-03-31 00:00:00.000
2013-04-30 00:00:00.000
2013-05-31 00:00:00.000
....
2017-12-31 00:00:00.000
答案 0 :(得分:1)
使用递归CTE
DECLARE @Strt DATE = '2013-01-01'
;WITH CTE
AS
(
SELECT
SeqNo = 1,
MyDate = DATEADD(M,1,DATEADD(D,-1,@Strt))
UNION ALL
SELECT
SeqN = SeqNo +1,
MyDate = DATEADD(m, 1, MyDate)
FROM CTE
WHERE SeqNo < DATEDIFF(m, @Strt,GETDATE())
)
SELECT
MyDate
FROM CTE
OPTION (maxrecursion 0)
答案 1 :(得分:1)
您也可以通过执行动态SQL查询来执行此操作。使用WHILE
循环来获取从开始日期到今天的所有月份的最后日期。
<强>查询强>
declare @today as date = getdate();
declare @start as date = '2013-01-01';
declare @months as int;
select @months = datediff(month, @start, @today);
declare @i as int= 1;
declare @t as table([dt] date);
while(@i <= @months)
begin
insert into @t
select dateadd(day, -1, (dateadd(month, @i, @start)));
set @i += 1;
end
select * from @t;
<强> Find a demo here 强>
答案 2 :(得分:1)
试试这个
DECLARE @StartDate DATE='2013-01-01';
WITH Tally AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nmbr
FROM master..spt_values
)
SELECT DATEADD(DAY,-1,DATEADD(MONTH,Nmbr,@StartDate)) AS EndOfNextMonth
FROM Tally
WHERE DATEADD(MONTH,Nmbr,@StartDate)<GETDATE();
Tally
cte将返回一个正在运行的数字列表。 master..spt_values
只是一张包含大量行的表...
查询将在日期中添加一个月并将其减少一天。
答案 3 :(得分:1)
我使用数字表,但是对于这个例子,我使用CTE生成了一个。我生成一个从-58到+ 1的数字列表,我用它来将这个月数添加到当前日期。然后我拿走这个日期的天数让我到月底:
WITH Numbers
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY a.Num) * -1 + 2 AS Num
FROM (VALUES (1),(2),(3),(5),(4),(6),(7),(8),(9),(10)) AS a(Num)
CROSS APPLY
(VALUES (1),(2),(3),(5),(6),(7)) As b(Num)
),
DateMinusMonths
AS
(
SELECT DATEADD(m, Num , CAST(getdate() AS Date)) As d
FROM Numbers
)
SELECT DATEADD(d, day(d) * -1, d) EOM
FROM DateMinusMonths
答案 4 :(得分:1)
这是我在尝试生成日期时使用的代码类型,我已将其更改为选择您想要的第一个月的最后一天(2013年1月31日)并要求它继续添加1个月直到今天#39;日期:
SELECT
DATEADD(MONTH, Number, '2013-01-31') AS [Date]
FROM
master..spt_values
WHERE
Type = 'P'
AND DATEADD(MONTH, Number, '2013-01-31') <= GETDATE()
答案 5 :(得分:0)
以下代码对您有所帮助,
declare @sDate datetime='2013-01-01', @eDate datetime= GETDATE()
;WITH mycte
AS (SELECT EOMONTH(@sDate) AS dt
UNION ALL
SELECT DATEADD(month, 1, dt) AS dt
FROM mycte
WHERE dt <@eDate
)
SELECT EOMONTH(dt) AS LastDayOfMth
FROM mycte
Order by LastDayOfMth
答案 6 :(得分:0)
这个公式有点复杂,但它避免了循环或递归的需要。
-- End of current month.
-- Replace GETDATE() with your column.
SELECT
CAST(DATEADD(SECOND, -1, DATEADD(MONTH, DATEDIFF(MONTH, '2000-01-01', GETDATE()) + 1, '2000-01-01')) AS DATE) AS EOMonth
;
它计算自基准日期以来经过的月数(我使用2001-01-01
,但您可以使用任何月份的第一个月)。它将相同数量的月份添加回基准日期。这给了我们下个月的开始。删除一秒会使我们回到当月的末尾。最后,作为日期进行转换会删除时间元素。
或者,您可以向数据库添加calendar table(也就是日期维度)。我管理的几乎每个数据库都有一个,我每天都使用它们。这是一个非常简单的例子:
Date StartOfMonth EndOfMonth
2018-01-01 2018-01-01 2018-01-31
2018-01-02 2018-01-01 2018-01-31
2018-01-03 2018-01-01 2018-01-31
... ... ...
2018-01-31 2018-01-01 2018-01-31
从SQL Server 2012开始,您可以使用EOMonth function。我知道这不是OP的选择,但它可能对其他人有所帮助。