SQL 结果按周、日分组

SQL results grouped by Weeks, Day

我有一个 table 如下所示:

Date        ServingTime   MeasuredValue
----------------------------------------
01-11-16    Breakfast     45
01-11-16    Lunch         50
01-11-16    Dinner        60
02-11-16    Breakfast     23
02-11-16    Lunch         45
02-11-16    Dinner        83
…       
…       
30-11-16    Breakfast     56
30-11-16    Lunch         16
30-11-16    Dinner        34

和如下查询:

DECLARE @DatePeriod date = '2016-11-30'

SELECT
  ServingTime,
  ISNULL([1], 0) AS 'Week 1',
  ISNULL([2], 0) AS 'Week 2',
  ISNULL([3], 0) AS 'Week 3',
  ISNULL([4], 0) AS 'Week 4',
  ISNULL([5], 0) AS 'Week 5'

FROM (SELECT
  ServingTime,
  DATEDIFF(WEEK, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0), Date) + 1 AS [Weeks],
  MeasuredValue AS 'Sale'

FROM HR.FoodCollectionEntry
-- Only get rows where the date is the same as the DatePeriod
-- i.e DatePeriod is 30th May 2011 then only the weeks of May will be calculated
WHERE DATEPART(MONTH, Date) = DATEPART(MONTH, @DatePeriod)) p
PIVOT (SUM(Sale) FOR Weeks IN ([1], [2], [3], [4], [5], [6])) AS pv

此查询输出如下:

ServingTime    Week 1    Week 2    Week 3    Week 4     Week 5
---------------------------------------------------------------
Breakfast      412       590       510       456        200
Dinner         329       525       529       529        321
Lunch          371       529       542       480        233

但我会在输出中也带上 Day 以比较每周星期日的销售额。如何查询得到如下输出?

Day        ServingTime  Week 1  Week 2  Week 3  Week 4  Week 5
---------------------------------------------------------------
Sunday     Breakfast    412     590     510     456     200
Sunday     Dinner       329     525     529     529     321
Sunday     Lunch        371     529     542     480     233
Monday     Breakfast    412     590     510     456     200
Monday     Dinner       329     525     529     529     321
Monday     Lunch        371     529     542     480     233
…                       
…                       
Saturday   Breakfast    412     590     510     456     200
Saturday   Dinner       329     525     529     529     321
Saturday   Lunch        371     529     542     480     233

只使用条件聚合:

select datename(weekday, fce.date) as dayOfWeek, servingTime,
       sum(case when weeks = 1 then sale else 0 end) as Week_1,
       sum(case when weeks = 2 then sale else 0 end) as Week_2,
       sum(case when weeks = 3 then sale else 0 end) as Week_3,
       sum(case when weeks = 4 then sale else 0 end) as Week_4,
       sum(case when weeks = 5 then sale else 0 end) as Week_5
from (select fce.*,
             datediff(week, dateadd(month, datediff(month, 0, Date), 0), Date) + 1 AS Weeks
      from HR.FoodCollectionEntry fce
     ) fce
where month(Date) = month(@DatePeriod) and
      year(Date) = year(@DatePeriod)  -- I assume you want this too
      group by datename(weekday, fce.date) as dayOfWeek, servingTime
order by max(datepart(weekday, fce.date)