2013-03-28 95 views
0

我需要動態選擇的值是日期,並因此發生變化(即每週或每月)。我想知道如何使用T-SQL的「執行」功能來做到這一點(SQL Server 2008中)使用動態sql創建一個帶有總和的表格

表瑞吉有4列,數據與此類似(有90K行):

Holder  Period  State Ttl 
Dell  2011-12-31 CA  5 
Dell  2012-01-31 PA  7 
Sony  2011-11-30 TX  8 
Sony  2013-02-28 FL  20 

總數是該州在該日結束的月份的「銷售額」。這一銷售數據跨越14個月。但是,它可能會增長到20個月。此外,日期會隨着時間的推移而改變,因爲它是連續數月。我只想得到州的總交易,以期間爲列。

我知道,刪除持有人和使用與SUM組,將水平做到這一點。我也知道,我知道所有的時期,我可以使用樞軸。但是,我希望Period是列,並且希望通過動態SQL來實現,因爲我還需要學習其他動態SQL。謝謝你的幫助。

最終結果應該是像

state 2011-11-30 2011-12-31... 2013-02-28 
CA  100   205   78 
WA  90   159   62 
CO  16   654   31 
TX  87   321   205 
NY  54   45   415 

回答

1

我認爲你需要做一個動態的支點,因爲列名是未知的,它們的數量也未可知。我在下面的代碼中做了類似的事情。 COALESCE是絕大部分的魔力,因爲它建立了一個名單來轉動。在我的示例中,「SysCode」將是您的「期間」列的等值線。

--Pull the data set 

DECLARE 
    @Query NVARCHAR(4000) 

INSERT INTO 
    #Rates 

SELECT 
    CAST(mrc.StartDay AS DATE) [Start Date], 
    CAST(mrc.EndDay AS DATE) [End Date], 
    dpe.NCCDayPart [Daypart], 
    dpe.NCCDayPartDescription [Description], 
    mrc.Network, 
    ru.SysCode, 
    mrc.Rate 

FROM 
    minimumratecards mrc 
    LEFT JOIN DaypartExtension dpe 
     ON mrc.DayPartSequence = dpe.Sequence 
     AND dpe.Division = 'CAMC' 
    LEFT JOIN #RetailUnit ru 
     ON mrc.RetailUnitCode = ru.RetailUnit 


WHERE 
    mrc.MinimumRateCardID = @MinimumRateCardID 



--Get a distinct list of syscodes that were returned  
SELECT DISTINCT 
    Syscode 

INTO 
    #Syscodes 

FROM 
    #Rates 



--Format the syscode list into a string to be used in the pivot table 
SELECT 
    @Cols = COALESCE(@Cols + ',[' + SysCode + ']', 
         '[' + SysCode + ']') 
FROM  
    #Syscodes 

ORDER BY 
    SysCode 



--Pivot the data 
SET @Query = 
    N'SELECT 
     [Start Date], 
     [End Date], 
     [Daypart], 
     [Description], 
     [Network], '+ 
     @Cols +' 
    FROM 
    (SELECT 
     [Start Date], 
     [End Date], 
     [Daypart], 
     [Description], 
     [Network], 
     [Rate], 
     [SysCode] 
    FROM #Rates AS t1) p 
    PIVOT 
     (
     MAX([Rate]) 
     FOR [SysCode] IN 
     ('+ 
     @Cols +') 
     ) AS pvt 
     ORDER BY [Network];' 


EXECUTE(@Query) 
1

由於您使用的是SQL Server,因此您可以使用PIVOT函數將行轉換爲列。

在跳轉到動態版本之前,更容易看到代碼是如何設置爲有限值或靜態值的。對於您的數據,您將使用:

select * 
from 
(
    select period, state, ttl 
    from regis 
) d 
pivot 
(
    sum(ttl) 
    for period in ([2011-11-30], [2011-12-31], [2013-02-28]) 
) piv; 

請參閱SQL Fiddle with Demo

您將需要創建將在數據透視中使用的不同period值的列表。創建這個列表中的代碼將類似於:

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Period) 
        from regis 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

的代碼,你將用來創建動態SQL是:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Period) 
        from regis 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT state, ' + @cols + ' from 
      (
       select period, state, ttl 
       from regis 
      ) x 
      pivot 
      (
       sum(ttl) 
       for period in (' + @cols + ') 
      ) p ' 

execute(@query) 
相關問題