按周数分组,包括空周和总计其他列

按周数分组,包括空周和总计其他列

问题描述:

我试图从SQL Server中的表中进行选择,以便它将我的FinalDate列分组为周数,并在下一个单元格中汇总该周的ThisApp列。我在网上看,我似乎无法找到我所追求的。按周数分组,包括空周和总计其他列

我想知道这是我在T-SQL中可以做到的吗?

这些目前都在我的表中的行:

FinalDate ThisApp 
    ------------------------ 
    15/04/2016 20459.92 
    29/05/2016 7521.89 
    30/05/2016 5963.61 
    31/05/2016 3293.72 
    03/06/2016 27413.20 
    04/06/2016 8392.16 
    05/06/2016 7789.46 
    05/06/2016 11414.73 
    10/06/2016 48893.46 
    11/06/2016 14685.47 
    11/06/2016 7030.03 

我想更换FinalDate柱,周数,总结了This App每个周数。

另外:

我需要它来显示连续周数,所以我不希望它跳过任何星期,因此,例如:

FinalDate ThisApp 
    ------------------------ 
    01/01/2016 10.00 -- (Would be week 1) 
    02/01/2016 10.00 -- (Would be week 1) 
    15/01/2016 10.00 -- (Would be week 3) 

将显示,如:

FinalDate ThisApp 
    ------------------------ 
    1   20.00 
    2   0.00 --This would show as 0.00 because there was no week 2. 
    3   10.00 

我明白这是一个非常具体的请求,这就是为什么我想知道如果我可以在SQL中做到这一点。

+0

一个好的技巧是在这里发布日期时,为了避免混淆使用MM/DD/YYYY。大多数人会采用这种格式,当你使用DD/MM/YYYY时,除非包括否则不可能的东西(比如'15/01/2016'),否则会引起混淆。 –

DECLARE @tmp table(dat datetime, 
        val float) 

insert into @tmp 
values ('15/04/2016' , 20459.92), 
     ('29/05/2016', 7521.89), 
     ('30/05/2016', 5963.61), 
     ('31/05/2016', 3293.72), 
     ('03/06/2016', 27413.20), 
     ('04/06/2016', 8392.16), 
     ('05/06/2016', 7789.46), 
     ('05/06/2016', 11414.73), 
     ('10/06/2016', 48893.46), 
     ('11/06/2016', 14685.47), 
     ('11/06/2016', 7030.03) 

SELECT Weeknumb, 
     ISNULL(sumvals,0) as weekval 
FROM 
    (SELECT DATEPART(ISOWK,DATEADD(wk,t2.number,'2016')) as Weeknumb 
    FROM master..spt_values t2 
    WHERE t2.type = 'P' 
    AND t2.number <= 255 
    AND YEAR(DATEADD(wk,t2.number,'2016'))=2016)allWeeks 
    LEFT JOIN 
    (SELECT sum(val) as sumvals, 
      datepart(ISOWK,dat) as weeks 
    FROM @tmp 
    GROUP BY datepart(ISOWK,dat)) actualData 
    ON weeks = Weeknumb 
    ORDER BY Weeknumb asc 

你去那里。 2016年的所有星期和您的价值总和

+0

此查询仅适用于特定年份(在本例中为2016年)。 –

SELECT DATEPART(WEEK, FinalDate) FinalDate 
,  SUM(ThisApp) ThisApp 
FROM  Your_Table 
GROUP BY DATEPART(WEEK, FinalDate) 

为了得到0数周没有,你必须创建一个表weeknumbers(1-52)和right join它的数据集存在。在这种情况下,你会得到这样的:

SELECT  wk.Number 
,    ISNULL(SUM(ThisApp), 0) 
FROM   Your_Table T 
RIGHT JOIN WeekNumbers wk 
      ON wk.Number = DATEPART(WEEK, T.FinalDate) 
GROUP BY  wk.Number 
+0

有趣,我会试试这个,赞赏。 –

+0

我可能不得不在周一试试这个,因为我必须在几分钟内离开周末,如果它适合我​​,我会在周一接受你的回答。 –

+0

祝你好运,祝你周末愉快 – HoneyBadger

HoneyBadger的答案很好,但它会将每年的第1周的价值组合在一起(所以1975年1月1日将与2016年1月1日分组)。为了避免这种情况,您需要将年份添加到分组中。

另外,正如他指出的那样,如果您希望返回NULL周,您还需要一个单独的表格。但是,你应该制作一个日历表(Google这个 - 它们很简单并被广泛使用),并且你不应该在1-52周内制作一个表格。

最后,为了确保您不会得到在所有年/周前返回0的记录,这些记录在数据之前或之后都会返回,您将需要添加开始日期和结束日期参数。您可以接受它们,也可以将它们设置为Your_Table中的第一个和最后一个FinalDate。

这里是你应该使用什么:

DECLARE @StartDate date = (SELECT MIN(FinalDate) FROM Your_Table), 
     @EndDate date = (SELECT MAX(FinalDate) FROM Your_Table) 

SELECT YEAR(C.BaseDate) AS [Year], 
     DATEPART(WEEK, C.BaseDate) AS [Week], 
     ISNULL(SUM(YT.ThisApp), 0) AS [This App Total] 
FROM  Calendar C 
LEFT OUTER JOIN Your_Table YT 
    ON C.BaseDate = CAST(YT.FinalDate AS DATE) 
WHERE C.BaseDate BETWEEN @StartDate AND @EndDate 
GROUP BY YEAR(C.BaseDate), 
     DATEPART(WEEK, C.BaseDate)