Sql server 透视查询的SQL Server 2008动态标题(每周)
我想创建一个动态标题,显示开始日期和结束日期之间的周数。我已经添加了周数和年份。现在我想在这几周和几年之间找到DATENAME,我需要修复这个bug 以下是我迄今为止所做的工作: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
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周,我发布了另一个解决方案,在一年中的第一个星期一启动周计数器