0

動的に選択する必要がある値は日付であるため、変更されます (つまり、毎週または毎月)。TSQL(SQL Server 2008)の「EXEC」関数を使用してこれを行う方法を知りたい

Table Regis には 4 つの列があり、次のようなデータがあります (90,000 行あります)。

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 で Group by を使用すると、これが水平方向に行われることがわかっています。また、すべての期間の知識があれば、ピボットを使用できることも知っています。ただし、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
4

2 に答える 2

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)
于 2013-03-28T15:47:02.227 に答える
1

Since you are using SQL Server you can use the PIVOT function to transform your rows into columns.

Before jumping into a dynamic version it is easier to see how the code is set up for limited or static values. For your data, you will use:

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;

See SQL Fiddle with Demo.

You will need to create a list of the distinct period values that will be used in the pivot. The code to create this list will be similar to :

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

The code that you will use to create the dynamic SQL is:

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)
于 2013-03-28T15:49:53.367 に答える