按周,日

时间:2016-12-11 12:35:48

标签: sql sql-server sql-server-2008 pivot

我有一张如下表:

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

1 个答案:

答案 0 :(得分:2)

只需使用条件聚合:

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)