2016-06-24 60 views
0

我想创建一个动态标题,显示开始日期和结束日期之间有多少星期。我已经添加了周数和年份。现在我想要在这些星期和年份之间的DATENAME,我需要修复这个错误。针对枢轴查询的SQL Server 2008动态标题(每周)

这是我到目前为止已经完成:

DECLARE @Query AS VARCHAR(MAX) 
DECLARE @Weeks INT 
DECLARE @DayNum INT 
DECLARE @tmp TABLE(WeekNum VARCHAR(MAX)) 
DECLARE @Headers VARCHAR(MAX) 
DECLARE @DayNumbers INT = 1 


DECLARE @FromDate DATETIME 
DECLARE @ToDate DATETIME 

SET @FromDate = '01/01/2016' 
SET @ToDate = '03/01/2016' 

SET @DayNum = 1 

DECLARE @Years INT = YEAR(@FromDate) 
DECLARE @DateRange INT = DATEDIFF(Week,@FromDate,'12/31/'+CAST(YEAR(@FromDate) AS VARCHAR)) 
SET @Weeks = DATEDIFF(Week, @FromDate, @ToDate) 

WHILE 1 = 1 
BEGIN 
    INSERT INTO @tmp(WeekNum) 
    VALUES ('Week ' + CAST(@DayNumbers AS VARCHAR(MAX)) + ' - ' + CAST(@Years AS VARCHAR)) 

    IF @DayNum <= @Weeks 
    BEGIN 
     SET @DayNum = @DayNum + 1 
     SET @DayNumbers = @DayNumbers + 1 

     IF @DateRange = @DayNumbers 
     BEGIN 
      SET @Years = @Years + 1 
      SET @DateRange = DATEDIFF(WEEK,'01/01/' + CAST(@Years AS VARCHAR),'12/31/' + CAST(@Years AS VARCHAR)) 
      SET @DayNumbers = 1 
     END 
    END 
    ELSE 
     BREAK  
END 

SELECT @Headers = ISNULL(@Headers + ',','') + QUOTENAME(t.WeekNum) 
FROM @tmp t 


SELECT * 
FROm @tmp 

这里是周的结果2016年1月1日2016年3月1日

enter image description here

让我们尝试不同的日期2016年1月1日Dec 31,2016

这是另一个问题。

enter image description here

它一路上升到2017年,即使它是唯一的,直到2016年12月

回答

2
Declare @DateStart Date = '2016-01-01' 
Declare @DateEnd Date = '2016-12-31' 

;with cteDate As (
    Select DateFrom = @DateStart 
    Union All 
    Select DateFrom= DateAdd(DD, 7, df.dateFrom) 
    From cteDate DF 
    Where DF.DateFrom <= @DateEnd 
) 
Select *,WeekNum = concat('Week ',DatePart(WEEK,DateFrom))+concat(' - ',Year(DateFrom)) 
From cteDate 
Where DateFrom<[email protected] 
option (maxrecursion 32767) 

注意查看您何时移除会发生什么其中DateFrom < = @ DateEnd最终选择

返回

DateFrom WeekNum 
2016-01-01 Week 1 - 2016 
2016-01-08 Week 2 - 2016 
2016-01-15 Week 3 - 2016 
2016-01-22 Week 4 - 2016 
2016-01-29 Week 5 - 2016 
2016-02-05 Week 6 - 2016 
2016-02-12 Week 7 - 2016 
2016-02-19 Week 8 - 2016 
2016-02-26 Week 9 - 2016 
2016-03-04 Week 10 - 2016 
2016-03-11 Week 11 - 2016 
2016-03-18 Week 12 - 2016 
2016-03-25 Week 13 - 2016 
2016-04-01 Week 14 - 2016 
2016-04-08 Week 15 - 2016 
2016-04-15 Week 16 - 2016 
2016-04-22 Week 17 - 2016 
2016-04-29 Week 18 - 2016 
2016-05-06 Week 19 - 2016 
2016-05-13 Week 20 - 2016 
2016-05-20 Week 21 - 2016 
2016-05-27 Week 22 - 2016 
2016-06-03 Week 23 - 2016 
2016-06-10 Week 24 - 2016 
2016-06-17 Week 25 - 2016 
2016-06-24 Week 26 - 2016 
2016-07-01 Week 27 - 2016 
2016-07-08 Week 28 - 2016 
2016-07-15 Week 29 - 2016 
2016-07-22 Week 30 - 2016 
2016-07-29 Week 31 - 2016 
2016-08-05 Week 32 - 2016 
2016-08-12 Week 33 - 2016 
2016-08-19 Week 34 - 2016 
2016-08-26 Week 35 - 2016 
2016-09-02 Week 36 - 2016 
2016-09-09 Week 37 - 2016 
2016-09-16 Week 38 - 2016 
2016-09-23 Week 39 - 2016 
2016-09-30 Week 40 - 2016 
2016-10-07 Week 41 - 2016 
2016-10-14 Week 42 - 2016 
2016-10-21 Week 43 - 2016 
2016-10-28 Week 44 - 2016 
2016-11-04 Week 45 - 2016 
2016-11-11 Week 46 - 2016 
2016-11-18 Week 47 - 2016 
2016-11-25 Week 48 - 2016 
2016-12-02 Week 49 - 2016 
2016-12-09 Week 50 - 2016 
2016-12-16 Week 51 - 2016 
2016-12-23 Week 52 - 2016 
2016-12-30 Week 53 - 2016 
+0

谢谢你的答案。有效!但我收到一个错误,递归只能处理100行。这种方法有没有其他选择?我正在考虑使用WHILE循环。 – ZeroCool

+0

如何使此查询动态?因为我在@DateStart于2016年1月5日尝试并在第一行显示2016-01-05第2周 - 2016年。那应该是2016-01-03第1周 - 2016年,因为这是2016年1月5日这一天的第一天。 – ZeroCool

+0

目前,我只是使用DatePart的WEEK,你想要提供的第一周开始日期? –

1

按照要求,该版本将启动一周计数器作为今年的第一个星期一的..

Declare @DateStart Date = '2016-01-01' 
Declare @DateEnd Date = '2016-12-31' 


Declare @FirstMonday Date,@yr int = Year(@DateStart) 
Set @FirstMonday = DateAdd(DD,1,case when datepart(weekday,dateadd(year,@yr-1900,0))=1 then dateadd(year,@yr-1900,1) else dateadd(dd,8-(datepart(weekday,dateadd(year,@yr-1900,0))),dateadd(year,@yr-1900,1)) end) 

;with cteDate As (
    Select WkCntr = 1,DateFrom = @FirstMonday 
    Union All 
    Select WkCntr = 1+df.WkCntr,DateFrom= DateAdd(DD, 7, df.dateFrom) 
    From cteDate DF 
    Where DF.DateFrom <= @DateEnd 
) 
Select *,WeekNum = concat('Week ',WkCntr)+concat(' - ',Year(DateFrom)) 
From cteDate 
Where DateFrom<[email protected] 
option (maxrecursion 32767) 



WkCntr DateFrom WeekNum 
1  2016-01-05 Week 1 - 2016 
2  2016-01-12 Week 2 - 2016 
3  2016-01-19 Week 3 - 2016 
... 
51  2016-12-20 Week 51 - 2016 
52  2016-12-27 Week 52 - 2016 
0

OK,这个人会开始一周计数器为1,在开始任何日期你供应。

我加了一点皱纹。我给了你DateR1和DateR2,以方便你在这两个日期之间汇总你的数据。

Declare @DateStart Date = '2016-01-15' 
Declare @DateEnd Date = '2016-12-31' 

;with cteDate As (
    Select WkCntr = 1,DateR1 = @DateStart, DateR2 = DateAdd(DD,6,@DateStart) 
    Union All 
    Select WkCntr = 1+df.WkCntr,DateR1= DateAdd(DD, 7, df.DateR1), DateR2 = DateAdd(DD,7,df.DateR2) 
    From cteDate DF 
    Where DF.DateR1 <= @DateEnd 
) 
Select *,WeekNum = concat('Week ',WkCntr)+concat(' - ',Year(DateR1)) 
From cteDate 
Where DateR1<[email protected] 
option (maxrecursion 32767) 

返回

WkCntr DateR1  DateR2  WeekNum 
1  2016-01-15 2016-01-21 Week 1 - 2016 
2  2016-01-22 2016-01-28 Week 2 - 2016 
3  2016-01-29 2016-02-04 Week 3 - 2016 
4  2016-02-05 2016-02-11 Week 4 - 2016 
5  2016-02-12 2016-02-18 Week 5 - 2016 
... 
49  2016-12-16 2016-12-22 Week 49 - 2016 
50  2016-12-23 2016-12-29 Week 50 - 2016 
51  2016-12-30 2017-01-05 Week 51 - 2016 

现在,这里是如何聚合数据的例子。假设

-- Let's create a dummy SALES Table 
Declare @SalesTable table (SalesDate date, Sales money) 
Insert Into @SalesTable values 
('2016-01-16',25), 
('2016-01-22',10), 
('2016-02-05',75), 
('2016-02-22',125) 

--- The Previous displayed cte 
Declare @DateStart Date = '2016-01-15' 
Declare @DateEnd Date = '2016-12-31' 

;with cteDate As (
    Select WkCntr = 1,DateR1 = @DateStart, DateR2 = DateAdd(DD,6,@DateStart) 
    Union All 
    Select WkCntr = 1+df.WkCntr,DateR1= DateAdd(DD, 7, df.DateR1), DateR2 = DateAdd(DD,7,df.DateR2) 
    From cteDate DF 
    Where DF.DateR1 <= @DateEnd 
), 
cteDateRange as (
    Select *,WeekNum = concat('Week ',WkCntr)+concat(' - ',Year(DateR1)) 
    From cteDate 
    Where DateR1<[email protected] 
) 
Select A.DateR1 
     ,A.DateR1 
     ,A.WeekNum 
     ,Sales=isnull(sum(Sales),0) 
From cteDateRange A 
Left Join @SalesTable B on (B.SalesDate between DateR1 and DateR2) 
Group By DateR1,DateR2,WeekNum 
Order By 1 

返回

DateR1  DateR1  WeekNum   Sales 
2016-01-15 2016-01-15 Week 1 - 2016 25.00 
2016-01-22 2016-01-22 Week 2 - 2016 10.00 
2016-01-29 2016-01-29 Week 3 - 2016 0.00 
2016-02-05 2016-02-05 Week 4 - 2016 75.00 
2016-02-12 2016-02-12 Week 5 - 2016 0.00 
2016-02-19 2016-02-19 Week 6 - 2016 125.00 
2016-02-26 2016-02-26 Week 7 - 2016 0.00 
2016-03-04 2016-03-04 Week 8 - 2016 0.00