2016-03-04 58 views
0

我很難搞清楚這一點。我檢查過類似的帖子,但他們只有一列作爲一行旋轉。雖然我需要轉動具有動態年份列的數據透視SQL表

我有以下查詢:

SELECT 
     Year([Date]) as Year 
     ,SUM([Drop]) as [Drop] 
     ,SUM([TicketsDistributed]) as [TicketsDistributed] 
     ,SUM([TicketsSold]) as [TicketsSold] 
     ,SUM([GrossTickets]) as [GrossTickets] 
     ,SUM([GrossTickets])/SUM(TicketsSold) as 'Per Cap' 
    FROM [dbo].[Tickets] 
    group by [Date] 

這給了我這樣的結果:

Year Drop TicketsDistributed TicketsSold GrossTickets Per Cap 
2016 222   100     5000  4000.00  0.800000 
2015 222   110     5000  4000.00  0.900000 
2014 222   120     5000  4000.00  1.00000 

而且我想以下幾點:

     2016 2015 2014 
Drop     222 222 222  
TicketsDistributed  100 110 120  
TicketsSold   5000 5000 5000  
GrossTickets   4000 4000 4000 
Per Cap    0.8  0.9 1 

基礎的在建議的答案這是我到目前爲止,但它不起作用

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(Year(Date)) 
        from [dbo].[SpringTrainings] t 
        cross apply 
        (
         select SUM([Drop]) as [Drop] 
     ,SUM([TicketsDistributed]) as [TicketsDistributed] 
     ,SUM([TicketsSold]) as [TicketsSold] 
     ,SUM([GrossTickets]) as [GrossTickets] 
     ,SUM([GrossTickets])/SUM(TicketsSold) as PerCap 
    FROM [dbo].[SpringTrainings] 
        ) c ([Drop],[TicketsDistributed],[TicketsSold],[GrossTickets],PerCap) 
        group by Year(Date) 
        order by Year(Date) 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 




set @query = 'SELECT [Drop],[TicketsDistributed],[TicketsSold],[GrossTickets],PerCap,' + @cols + ' 
      from 
      (
       select SUM([Drop]) as [Drop] 
     ,SUM([TicketsDistributed]) as [TicketsDistributed] 
     ,SUM([TicketsSold]) as [TicketsSold] 
     ,SUM([GrossTickets]) as [GrossTickets] 
     ,SUM([GrossTickets])/SUM(TicketsSold) as PerCap 
     FROM [dbo].[SpringTrainings] 

      ) x 
      pivot 
      (
       max(Year([Date])) 
       for Year([Date]) in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 
+0

SQL是不是不適合這種需要,你怎麼使用呢?在報告中?通過HTML? –

回答

1

如果您希望在T-SQL中繼續使用pivot操作符,那麼首先您需要「取消」現有查詢,以便擁有Year,Label和Value。雖然T-SQL中有一個unpivot運算符,但我發現使用CROSS APPLY和VALUES要簡單得多,速度也一樣快(關於Brad Schultz的方法read this article的更多內容),我特別喜歡它,因爲我可以輕鬆地將結果可視化我佈置值對的方式。

SELECT 
     d.Year 
    , a.label 
    , a.value 
FROM (
     SELECT 
      YEAR([Date]) AS [Year] 
      , SUM([Drop]) AS [Drop] 
      , SUM([TicketsDistributed]) AS [TicketsDistributed] 
      , SUM([TicketsSold]) AS [TicketsSold] 
      , SUM([GrossTickets]) AS [GrossTickets] 
      , SUM([GrossTickets])/SUM(TicketsSold) AS [PerCap] 
     FROM [dbo].[Tickets] 
     GROUP BY 
      [Year] 
    ) AS t 
     CROSS APPLY (/* now transform into 5 rows per year but just 1 value column */ 
      VALUES 
       ('Drop',t.Drop) 
       , ('TicketsDistributed',t.TicketsDistributed) 
       , ('TicketsSold',t.TicketsSold) 
       , ('GrossTickets',t.GrossTickets) 
       , ('PerCap',t.PerCap) 
    ) AS a (label, value) 

該查詢(上面)替換了動態SQL中的派生表x。一旦數據被按摩到表單中的支點看起來簡單的方法:

 ) x 
     pivot 
     (
      max([x.Value]) 
      for [x.Year] in ([2014],[2015],[2016]) 
     ) p 

爲了您@cols我會建議一些簡單的像這樣:

SELECT DISTINCT 
    QUOTENAME(Year([date])) 
FROM [dbo].[Tickets] 

TIP:如果你需要一種方法對行進行排序,包括在橫向施加過,這樣的:

 CROSS APPLY (/* now transform into 5 rows per year but just 1 value column */ 
      VALUES 
       (1, 'Drop',t.Drop) 
       , (2, 'TicketsDistributed',t.TicketsDistributed) 
       , (3, 'TicketsSold',t.TicketsSold) 
       , (4, 'GrossTickets',t.GrossTickets) 
       , (5, 'PerCap',t.PerCap) 
    ) AS a (row_order, label, value) 

,然後將該[row_order]可以用來進行樞軸之後。

讓整體看起來是這樣的:

DECLARE @cols AS nvarchar(max) 
     , @query AS nvarchar(max) 

SELECT @cols = STUFF((
      SELECT DISTINCT 
        ',' + QUOTENAME(YEAR([date])) 
      FROM [dbo].[Tickets] 
      FOR xml PATH (''), TYPE 
    ) 
     .value('.', 'NVARCHAR(MAX)') 
     , 1, 1, '') 


SET @query = 'SELECT [Year], [Label], ' 
      + @cols 
      + ' FROM (
        SELECT 
         d.Year 
         , a.label 
         , a.value 
        FROM (
         SELECT 
           YEAR([Date]) AS [Year] 
          , SUM([Drop]) AS [Drop] 
          , SUM([TicketsDistributed]) AS [TicketsDistributed] 
          , SUM([TicketsSold]) AS [TicketsSold] 
          , SUM([GrossTickets]) AS [GrossTickets] 
          , SUM([GrossTickets])/SUM(TicketsSold) AS [PerCap] 
         FROM [dbo].[Tickets] 
         GROUP BY 
           [Year] 
       ) AS d 
         CROSS APPLY (
            VALUES 
             (1,''Drop'',t.Drop) 
             , (2,''TicketsDistributed'',t.TicketsDistributed) 
             , (3,''TicketsSold'',t.TicketsSold) 
             , (4,''GrossTickets'',t.GrossTickets) 
             , (5,''PerCap'',t.PerCap) 
         ) AS a (row_order,label,value) 
       ) x 
      pivot 
      (
       max([x.Value]) 
       for [x.Year] in (' + @cols + ') 
      ) p 
      ORDER BY [row_order]' 

EXECUTE sp_executesql @query;