SQL - 每月最后14天的临时表

时间:2016-12-14 15:43:15

标签: sql sql-server tsql

我正在尝试根据一个参数创建一个临时表,该参数返回给定范围内每个月的最后14天。例如:

@StartDate = '20160101'
@EndDate = '20160401' 

然后临时表应该包含Jan,Feb,Mar和amp;的最后14天(日期形式)。 2016年4月。

这是我尝试过的:

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 ) 

2 个答案:

答案 0 :(得分:0)

使用递归cte生成给定范围内的所有日期。

此后获取每个月的天数,并从该数字中减去每月的日期,并在每个月中获得最后14天(差异从0到13)。

declare @StartDate date = '2016-01-01';
declare @EndDate date = '2016-04-30';

With CTE as (Select @StartDate as start_date
             UNION ALL 
             Select dateadd(dd,1,start_date) from CTE Where start_date<@EndDate) 
select start_date
from (select *,count(*) over(partition by year(start_date),month(start_date)) days_in_month
      from CTE
     ) x
where days_in_month-datepart(dd,start_date) <=13
OPTION (MAXRECURSION 0)

<强> Sample Demo

答案 1 :(得分:0)

    --generates all days belonging to all months in the range, then takes only the 
    --last 14 days of every month - dates outside of the range, but in those
    --actual months, can be valid to return
    DECLARE @StartDate date = '20160125';
    DECLARE @EndDate date = '20160401';

    WITH CTE AS (SELECT DATEADD(day,1 - day(@StartDate) , @StartDate) CD
                  UNION ALL SELECT DATEADD(day, 1, CD) FROM CTE WHERE CD < dateadd(day,-1,dateadd(m,1,dateadd(day,1 - day(@ENDDATE), @ENDDATE))))
        select * into #temp from CTE  WHERE DAY(dateadd(day,
                            -1,
                                dateadd(m,
                                        1,
                                        dateadd(day,
                                                1 - day(cd), 
                                                cd
                                                )
                                        )
                            )
                    ) - DAY(CD) < 14
        option (maxrecursion 0);
        select * from #temp;