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

Group by week number including empty weeks and sum other column

我正在尝试从 SQL 服务器中的 table select,以便它将我的 FinalDate 列分组为周数并对 ThisApp 下一个单元格中那一周的列。我上网查了一下,似乎找不到我要找的东西。

我想知道这是否是我可以在 T-SQL 中做的事情?

目前这些是我 table 中的行:

    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 中做到这一点。

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

为了获得数据集中不存在的周数 0,您必须创建一个 table,其中包含周数 (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
 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 年所有周的价值总和

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

此外,正如他指出的那样,如果您还希望返回 NULL 周数,则需要一个单独的 table。然而,你应该制作一个日历 table(Google 这个 - 它们很简单并且被广泛使用)并且你不应该只制作一个包含第 1-52 周的 table。

最后,为确保您不会为数据之前或之后的所有 Year/Weeks 返回 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)