过去12个月的SQL函数

时间:2013-12-10 11:17:24

标签: sql sql-server function date

我正在寻找一个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

任何人都知道该怎么办?

6 个答案:

答案 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
....