我有两个日期,例如08/08/2013和11/11/2013,我需要从8月到11月的每个月的最后一个日期在一个表中,以便我可以遍历表格来单独选择这些日期。
我知道如何选择任何一个月的最后日期,但我被一个日期范围所困扰。
友好的帮助,我们将非常感激。
注意:我使用的是Sql 2008,日期范围可能是1个月,2个月或6个月或一年或者最大值。
答案 0 :(得分:7)
您可以使用CTE获取定义范围内该月的所有最后几天
Declare @Start datetime
Declare @End datetime
Select @Start = '20130808'
Select @End = '20131111'
;With CTE as
(
Select @Start as Date,Case When DatePart(mm,@Start)<>DatePart(mm,@Start+1) then 1 else 0 end as [Last]
UNION ALL
Select Date+1,Case When DatePart(mm,Date+1)<>DatePart(mm,Date+2) then 1 else 0 end from CTE
Where Date<@End
)
Select * from CTE
where [Last]=1 OPTION ( MAXRECURSION 0 )
答案 1 :(得分:2)
我创建了一个表变量,用@startDate
和@endDate
之间的所有日期填充它,并搜索了该月的最大日期。
declare @tmpTable table (dates date)
declare @startDate date = '08/08/2013'
declare @endDate date = '11/11/2013'
while @startDate <= @endDate
begin
insert into @tmpTable (dates) values (@startDate)
set @startDate = DATEADD(DAY, 1, @startDate)
end
select max(dates) as [Last day] from @tmpTable as o
group by datepart(YEAR, dates), datepart(MONTH, dates)
结果:
Last day
2013-08-31
2013-09-30
2013-10-31
2013-11-11
也要在11月的最后一天,这可以在循环之前使用:
set @endDate = DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @endDate) + 1, 0))
答案 2 :(得分:2)
DECLARE @tmpTable table (LastDates DATE);
DECLARE @startDate DATE = '01/01/2012'; --1 Jan 2012
DECLARE @endDate DATE = '05/31/2012'; --31 May 2012
DECLARE @tmpEndDate DATE;
SET @startDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@startDate)+1,1));
SET @tmpEndDate = DATEADD(DAY, 1, @endDate);
WHILE (@startDate <= @tmpEndDate)
BEGIN
INSERT INTO @tmpTable (LastDates) values (DATEADD(DAY, -1, @startDate));
SET @startDate = DATEADD(MONTH, 1, @startDate);
END
SELECT [LastDates] FROM @tmpTable;
<强>输出:强>
示例:1
@startDate DATE = '01/01/2012'; --1 Jan 2012
@endDate DATE = '05/31/2012'; --31 May 2012
LastDates
----------
2012-01-31
2012-02-29
2012-03-31
2012-04-30
2012-05-31
示例:2
@startDate DATE = '11/01/2011'; --1 Nov 2011
@endDate DATE = '03/13/2012'; --13 Mar 2012
LastDates
----------
2011-11-30
2011-12-31
2012-01-31
2012-02-29
答案 3 :(得分:1)
以下脚本演示了用于查找上一个,当前和下个月的最后一天的脚本。
----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth
如果您想查找任何指定日期的最后一天,请使用以下脚本。
--Last Day of Any Month and Year
DECLARE @dtDate DATETIME
SET @dtDate = '8/18/2007'
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0))
LastDay_AnyMonth
ResultSet:
LastDay_AnyMonth
源 - SQL Server Central。
答案 4 :(得分:1)
您可以使用递归CTE执行此操作,请注意MAXRECURSION
OPTION
可以阻止无限循环:
DECLARE @StartDate DATE = '2013-08-08'
DECLARE @EndDate DATE = '2013-11-11'
;WITH dateCTE
AS
(
SELECT CAST(DATEADD(M, 1,DATEADD(d, DAY(@StartDate) * -1, @StartDate)) AS DATE) EndOFMonth
UNION ALL
SELECT CAST(DATEADD(M, 2,DATEADD(d, DAY(EndOFMonth) * -1, EndOFMonth)) AS DATE)
FROM dateCTE
WHERE EndOFMonth < DATEADD(d, DAY(@EndDate) * -1, @EndDate)
)
SELECT *
FROM dateCTE
OPTION (MAXRECURSION 30);
返回
EndOFMonth
----------
2013-08-31
2013-09-30
2013-10-31
答案 5 :(得分:0)
试试这个 最后一行(where)是日期过滤的可选项
declare @table table
(
thisdate date
)
insert into @table values ('12/01/2013'),('05/06/2013'),('04/29/2013'),('02/20/2013')
select *,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,thisdate)+1,0))
LastDay from @table
where thisdate between 'givendate' and 'givendate'
以下示例适用于所有日期
thisdate lastday
2013-12-01 2013-12-31 23:59:59.000
2013-05-06 2013-05-31 23:59:59.000
2013-04-29 2013-04-30 23:59:59.000
2013-02-20 2013-02-28 23:59:59.000
答案 6 :(得分:0)
以下CTE为您提供从1900年2月到26世纪中期(在我的机器上)的每个月的最后一天:
;with LastDaysOfMonths as (
select DATEADD(month,
ROW_NUMBER() OVER (ORDER BY so.object_id),
'19000131') as Dt
from sys.objects so,sys.objects so1
)
select * from LastDaysOfMonths
将它用作较大查询的一部分或将其过滤到您想要的日期应该很容易。您可以根据需要通过更改常量19000131
来调整年份范围。唯一重要的事情是确保你使用了31天的月份,并且总是在第31天使用常数。
答案 7 :(得分:0)
不需要使用公共表表达式或类似的东西 - 这个简单的查询将执行此操作:
SELECT DATEADD(d, -1, DATEADD(mm, DATEDIFF(m, 0, DATEADD(m, number, '2013-08-08')) + 1, 0)) AS EndOfMonth
FROM master.dbo.spt_values
WHERE 'P' = type
AND DATEADD(m, number, '2013-08-08') < '2013-11-11';
答案 8 :(得分:0)
尽管问题是@bummi已经回答的最后一天。
但这是第一次约会的解决方案,可能对某人有帮助。
获取@FromDate
和@ToDate
之间所有月份的开始日期。
DECLARE @FromDate DATETIME = '2019-08-13'
DECLARE @ToDate DATETIME = '2019-11-25'
;WITH CTE
AS
(
SELECT DATEADD(DAY, -(DAY(@FromDate) - 1), @FromDate) AS FirstDateOfMonth
UNION ALL
SELECT DATEADD(MONTH, 1, FirstDateOfMonth)
FROM CTE
WHERE FirstDateOfMonth < DATEADD(DAY, -(DAY(@ToDate) - 1), @ToDate)
)
SELECT * FROM CTE
这是结果
--Result
2019-08-01 00:00:00.000
2019-09-01 00:00:00.000
2019-10-01 00:00:00.000
2019-11-01 00:00:00.000