我正在寻找一个SQL函数,它给出了过去12个月的开始日期和结束日期。假设你选择10.Dec,它会得到一个结果:
- StartDate -- EndDate
- 2013-11-01 - 2013-11-30
- 2013-10-01 - 2013-10-31
- 2013-09-01 - 2013-09-30
所以它持续了12个月。
我尝试修改我们的旧功能,但最终完全失去了困惑。
ALTER FUNCTION [dbo].[Last12Months](@Date date) RETURNS TABLE
AS
Return
(
with cte as (
SELECT DATEADD(mm, DATEDIFF(mm, 01, @Date), 01) AS Start,
DATEADD(mm, DATEDIFF(mm, -12, @Date), -12) AS EndDate
union all
select Start - 1, EndDate - 1 from cte
where Start >= @Date )
select CAST(Start as DATE) StartDate, CAST(EndDate as DATE) EndDate from cte)
像这样运行:
select * from dbo.Last12Months ('2013-12-10')
得到了:
- StartDate - EndDate
- 2013-12-02 - 2013-12-20
任何人都知道该怎么办?
答案 0 :(得分:2)
这似乎可以完成这项工作 - 无论您是想将它放在一个函数中,还是只想放在需要数据的地方:
; With Numbers as (
select ROW_NUMBER() OVER (ORDER BY number ) as n
from master..spt_values
), Months as (
select DATEADD(month,n,'20010101') as start_date,
DATEADD(month,n,'20010131') as end_date
from Numbers
)
select * from Months
where DATEDIFF(month,start_date,GETDATE()) between 0 and 11
(如果您想根据其他日期获取,请替换GETDATE()
的任何其他日期)
(在我的机器上,这可以产生从2001年1月到至少下个世纪的任何月份 - 如果您还需要更早或更晚的日期,可以调整它)
答案 1 :(得分:2)
请尝试使用CTE:
ALTER FUNCTION [dbo].[Last12Months]
(
@Date datetime
) RETURNS @tbl TABLE (Start datetime, EndDate datetime)
AS
BEGIN
WITH T AS(
SELECT
DATEADD(month, DATEDIFF(month, 0, @Date), 0) AS Start,
DATEADD(d, -DAY(DATEADD(m,1,@date)),DATEADD(m,1,@date)) AS EndDate,
12 Cnt
UNION ALL
SELECT
DATEADD(month, -1, Start),
DATEADD(d, -DAY(DATEADD(m,1,Start-1)),DATEADD(m,1,Start-1)),
Cnt-1
FROM
T
WHERE
Cnt-1>0
)
INSERT INTO @tbl
(Start, EndDate)
SELECT
Start, EndDate
FROM T
RETURN
END
答案 2 :(得分:1)
该死的,你必须快速上SO!
好好利用CTE:我已经学到了一点回答......
alter function Last12Months(@d date) returns table
as
return(
with cte as (
select
dateadd(month, datepart(mm,@d)-13,
dateadd(year,datepart(yyyy,@d)-1900,0)
)
as start
union all
select dateadd(mm, 1, start) from cte
where start < @d)
select start, dateadd(mm, 1, start) ends from cte
where start < @d
)
go
select * from Last12Months('2014-06-04')
感谢删除转换为varchar Date serial in SQL?
这将返回13个月:从去年6月到今年6月,包括在内。
要返回前12个月,不包括当前的6月,请将最终开始时间&lt; @d更改为
where start < dateadd(month, datepart(mm,@d)-1,
dateadd(year,datepart(yyyy,@d)-1900,0))
结束时间是下个月第一天的00:00。
答案 3 :(得分:1)
检查一下,
Declare @i date='2013-12-10'
;with cte as
(Select dateadd(month,datediff(month,0,@i)-1,0) StartDate
,dateadd(day,-1,dateadd(month,datediff(month,0,@i),0)) EndDate ,1 rownum
Union all
select dateadd(month,-1,StartDate),dateadd(day,-1,StartDate),rownum+1 rownum from cte where rownum<12 )
select * from cte
答案 4 :(得分:0)
试试这可能会对你有所帮助
select top 12 *
from YourTable
where dateOf between @DateFrom and @DateTo
order by dateOf desc
答案 5 :(得分:0)
@Lebowski下面的脚本将按时间顺序为您提供指定日历月的开始和结束日期
DECLARE @nMonths TINYINT
SET @nMonths = 60
SELECT FORMAT(DATEADD(month, n.n - @nMonths+1+ DATEDIFF(month, 0, GETDATE()) -1 ,0), 'yyyy-MM-dd') AS MonthStartDate
, FORMAT(DATEADD(dd, -1, DATEADD(month, n.n - @nMonths+1 + DATEDIFF(month, 0, GETDATE()),0)), 'yyyy-MM-dd') AS MonthEndDate
FROM (SELECT TOP(@nMonths) n = ROW_NUMBER() OVER (ORDER BY NAME)
FROM master.dbo.syscolumns) n
示例输出
MonthStartDate MonthEndDate
2011-04-01 2011-04-30
2011-05-01 2011-05-31
2011-06-01 2011-06-30
2011-07-01 2011-07-31
2011-08-01 2011-08-31
2011-09-01 2011-09-30
2011-10-01 2011-10-31
2011-11-01 2011-11-30
2011-12-01 2011-12-31
....