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

时间:2016-05-06 12:44:08

标签: sql sql-server group-by week-number

我正在尝试从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中执行此操作。

3 个答案:

答案 0 :(得分:1)

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

为了在数据集中不存在数周的0,您必须创建一个包含周数(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

答案 1 :(得分:1)

 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年的所有周,您的价值总和

答案 2 :(得分:0)

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

另外,正如他所指出的,如果你希望返回NULL周,你还需要一个单独的表。但是,你应该制作一个日历表(谷歌这个 - 它们很简单并且被广泛使用),你不应该仅仅制作一个包含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)