2012-03-08 52 views
4

我正在写一份报告,需要显示一周的收据,按地点分组,并为每周的每一天分列。这将通过SSRS和SQL Server 2008 R2提供。最终的结果应该是这样的:(但所有7个星期几)TSQL报告 - 星期几的数据透视数据?

Location Monday Tuesday 
Building3 $100  $75 
Building4 $25  $35 
Building5 $105  $21 

我写了下面的T-SQL SELECT语句从我的报告表变量(@reporting)得到这个数据。随后打算按位置对输出进行分组以获得上面显示的布局。

原始数据在单行中列出接收日期,总计和位置。我想旋转数据,以便一周中的一天处于最佳状态。有一个更好的方法来做到这一点,比你看到下面。任何帮助?

SELECT 
     LocationKey.Location 
     ,Sunday.Cost as Sunday 
     ,Monday.Cost as Monday 
    FROM 

     (
      SELECT DISTINCT Location 
      FROM @reporting 
      WHERE Location NOT IN ('Building01', 'Building02', '') 
     ) AS LocationKey 

    LEFT JOIN 

(SELECT 

sunday.Location 
,sunday.Cost 

FROM @reporting as sunday (nolock) 

WHERE DATEPART(weekday,sunday.ReceiptDate)= 1 

     ) AS Sunday 
     ON Sunday.Location = LocationKey.Location 

LEFT JOIN 

(SELECT 
Monday.Location, 
Monday.Cost 

FROM @reporting as Monday (nolock) 

WHERE DATEPART(weekday,Monday.ReceiptDate)= 2 

     ) AS Monday 
     ON Monday.Location = LocationKey.Location 

回答

6

可能做到这一点的最简单方法是PIVOTDATENAME

SELECT location, 
     [Saturday], 
     [Sunday], 
     [Monday], 
     [Tuesday], 
     [Wednesday], 
     [Thursday], 
     [Friday] 
FROM (SELECT COST, 
       location, 
       Datename(weekday, receiptdate) DAY 
     FROM @reporting 
     WHERE location NOT IN ('Building01', 'Building02', '')) p 
     PIVOT ( 
     SUM (COST) 
     FOR DAY IN ([Saturday], [Sunday], [Monday], [Tuesday], [Wednesday], 
     [Thursday], [Friday])) pvt 

看到它在这个data.se query

工作的另一种方法是使用几个自联接,但不能做子查询。这里的关键是加入条款

SELECT LocationKey.Location, 
     SUM(Sunday.Cost) As [Sunday], 
     SUM(Monday.Cost) As [Monday], 
     SUM(Tuesday.Cost) As [Tuesday], 
     SUM(Wednesday.Cost) As [Wednesday], 
     SUM(Thursday.Cost) As [Thursday], 
     SUM(Friday.Cost) As [Friday], 
     SUM(Saturday.Cost) As [Saturday] 
FROM 
     (SELECT DISTINCT Location 
      FROM @reporting 
      WHERE Location NOT IN ('Building01', 'Building02', '')) LocationKey 
     LEFT JOIN @Reporting Sunday 
     ON LocationKey.Location = Sunday.Location 
     AND DATEPART(weekday,sunday.ReceiptDate)= 1 
     LEFT JOIN @Reporting Monday 
     ON LocationKey.Location = Monday.Location 
     AND DATEPART(weekday,Monday.ReceiptDate)= 2 
     LEFT JOIN @Reporting Tuesday 
     ON LocationKey.Location = Tuesday.Location 
     AND DATEPART(weekday,Tuesday.ReceiptDate)= 3 
     LEFT JOIN @Reporting Wednesday 
     ON LocationKey.Location = Wednesday.Location 
     AND DATEPART(weekday,Wednesday.ReceiptDate)= 4 
     LEFT JOIN @Reporting Thursday 
     ON LocationKey.Location = Thursday.Location 
     AND DATEPART(weekday,Thursday.ReceiptDate)= 5 
     LEFT JOIN @Reporting Friday 
     ON LocationKey.Location = Friday.Location 
     AND DATEPART(weekday,Friday.ReceiptDate)= 6   
     LEFT JOIN @Reporting Saturday 
     ON LocationKey.Location = Saturday.Location 
     AND DATEPART(weekday,Saturday.ReceiptDate)= 7 

你应该注意的是,你应该调用SET DATEFIRST或使用@@DATEFIRST偏移,当您使用DATEPART(weekday..

来保护您的查询从默认设置更改和破坏您的查询的可能性
+0

好吧,这支点看起来真棒。现在尝试。 – bluehiro 2012-03-08 19:17:59

+0

好的,我尝试了两种方法,他们都很好地工作。但是这个关键点很容易实现!非常感谢你,这正是我所期待的。我需要写一堆这些,所以我会用Pivot写所有这些。 – bluehiro 2012-03-08 19:52:20

+0

最后的评论,我只是重复使用它在15分钟内推出类似的报告。嘿,是的! – bluehiro 2012-03-08 20:08:28

0

这PIVOT查询应该得到你想要的东西:

select Location, Cost_D1, Cost_D2, Cost_D3, Cost_D4, Cost_D5, Cost_D6, Cost_D7 
from (
    select Location, 'Cost_D' + convert(varchar,datepart(weekday,ReceiptDate)) as FieldName, Cost 
    from @reporting 
) s 
pivot 
(
    sum(Cost) 
    for FieldName 
    in (Cost_D1, Cost_D2, Cost_D3, Cost_D4, Cost_D5, Cost_D6, Cost_D7) 
) p 
+0

你不需要*聚合结果......在数据透视后*这是SUM(成本)的作用 – 2012-03-08 19:34:08

+0

是的,我的不好,你是对的。我正在考虑提及按地点分组的问题,甚至没有考虑到已经按照设定的方式进行分组。从我的答案中删除误导性信息。 – Clark 2012-03-08 19:46:44

+0

对于我的许多疑问,这是一个很好的观点。做一次计算,而不是一遍又一遍。 – bluehiro 2012-03-08 19:48:21