Sql server 透视查询的SQL Server 2008动态标题(每周)

Sql server 透视查询的SQL Server 2008动态标题(每周),sql-server,dynamic,pivot,Sql Server,Dynamic,Pivot,我想创建一个动态标题,显示开始日期和结束日期之间的周数。我已经添加了周数和年份。现在我想在这几周和几年之间找到DATENAME,我需要修复这个bug 以下是我迄今为止所做的工作: DECLARE @Query AS VARCHAR(MAX) DECLARE @Weeks INT DECLARE @DayNum INT DECLARE @tmp TABLE(WeekNum VARCHAR(MAX)) DECLARE @Headers VARCHAR(MAX) DECLARE @DayNumbers

我想创建一个动态标题,显示开始日期和结束日期之间的周数。我已经添加了周数和年份。现在我想在这几周和几年之间找到DATENAME,我需要修复这个bug

以下是我迄今为止所做的工作:

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日之间数周的结果

让我们试试2016年1月1日和2016年12月31日的不同日期

这是另一个问题


它一直持续到2017年,尽管它只会按照要求持续到2016年12月,但该版本将从今年的第一个星期一开始使用周计数器

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<=@DateEnd
 option (maxrecursion 32767)
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<=@DateEnd
 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

根据要求,此版本将从一年中的第一个星期一开始运行周计数器

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<=@DateEnd
 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

好的,这一个将从您提供的任何日期开始,以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<=@DateEnd
 option (maxrecursion 32767)
下面是一个如何聚合数据的示例。让我们假设

-- 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<=@DateEnd
)
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

好的,这一个将从您提供的任何日期开始,以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<=@DateEnd
 option (maxrecursion 32767)
下面是一个如何聚合数据的示例。让我们假设

-- 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<=@DateEnd
)
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

谢谢你的回答。成功了!但是我收到一个错误,递归只能处理100行。有没有其他方法可以替代这种方法?我正在考虑使用WHILE循环。如何使此查询动态化?因为我在@DateStart中尝试了2016年1月5日,并在第一行显示了2016-01-05第2-2016周。这应该是2016-01-03第1周-2016年,因为这是2016年1月5日这一周的第一天。目前,我只是使用了DatePart这一周,是否希望您提供的开始日期为第1周?在DateAdd函数中,将7更改为1。你将在第一周的第一和第二周学习。第三个是在第二周,我发布了另一个解决方案,在一年的第一个星期一启动周计数器谢谢你的回答。成功了!但是我收到一个错误,递归只能处理100行。有没有其他方法可以替代这种方法?我正在考虑使用WHILE循环。如何使此查询动态化?因为我在@DateStart中尝试了2016年1月5日,并在第一行显示了2016-01-05第2-2016周。这应该是2016-01-03第1周-2016年,因为这是2016年1月5日这一周的第一天。目前,我只是使用了DatePart这一周,是否希望您提供的开始日期为第1周?在DateAdd函数中,将7更改为1。你将在第一周的第一和第二周学习。第三个是在第2周,我发布了另一个解决方案,在一年中的第一个星期一启动周计数器