1

次の作品:

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

SET @cols = 
STUFF
    (
        (
        SELECT   ',' + QUOTENAME(b."NewName")
        FROM    (
                    SELECT  myKey, 
                        win = SUM(win)
                    FROM    xxx.dbo.yyy
                    GROUP BY myKey
                    ) x
                    INNER JOIN #NameSwitch b ON
                        x.myKey = b.myKey
        ORDER BY x.win DESC
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'');


SET @query =    
    'SELECT [Measure],' + @cols + ' 
    FROM  
        (
            SELECT  [NewName], [Measure], [Amount]
            FROM    #UnpivottedData x
        ) x
        PIVOT 
        (
            SUM(Amount)
            FOR [NewName] in (' + @cols + ')
        ) p ';

EXECUTE(@query);

しかし、問題は、結果を一時テーブルに入力し、#xxx後でこのデータをを介して使用できるようにしたいことSELECT * FROM #xxxです。

CREATE上記を実行する前に#xxxを使用する必要がありdynamic sqlますか?もしそうなら、誰かがこれが行われている例の方向に私を向けることができます。

4

3 に答える 3

2

句に含めて変更してみてください

SET @query =    
'SELECT [Measure],' + @cols + ' 
 into ##xxx
FROM  
    (
        SELECT  [NewName], [Measure], [Amount]
        FROM    #UnpivottedData x
    ) x
    PIVOT 
    (
        SUM(Amount)
        FOR [NewName] in (' + @cols + ')
    ) p ';

これにより、結果の一時テーブルが作成されます...

選択する前に本当に作成したい場合..

create table ステートメントを作成するには、列の型を収集する必要があります。

于 2013-02-19T14:23:36.150 に答える
2

フレデリックはほぼ正しい -

動的 SQL は、呼び出しバッチとは別のスコープで実行されます。動的 SQL バッチ内で宣言された一時オブジェクト (テーブル、変数) は、動的 SQL バッチ内でのみ使用できます。グローバルSELECT INTO一時テーブルを作成できます。これらは接続固有であり、動的 SQL バッチ全体で保持されるためです。

sp_executesql

于 2013-02-19T14:29:57.570 に答える
1

列名を取得できるようですので、列タイプを取得できると思います。だからあなたはこれを行うことができます(疑似コード)

CREATE TABLE #XXX (Measure <type>)
//
   generate scripts like 
SET @SQL = N'ALTER TABLE #XXX ADD '+ ColumnName+' '+ColumnTypeInfo
EXEC SP_ExecuteSQL @SQL
//

SET @query =    
    'INSERT INTO #XXX ([MEASURE], '+@cols+')
     SELECT [Measure],' + @cols + ' 
    FROM  
        (
            SELECT  [NewName], [Measure], [Amount]
            FROM    #UnpivottedData x
        ) x
        PIVOT 
        (
            SUM(Amount)
            FOR [NewName] in (' + @cols + ')
        ) p ';

EXECUTE(@query);

PS

  1. 私自身が選ぶでしょうEXEC sp_executeSQL @SQLEXEC (@SQL)、この場合は好みの問題です
  2. コードを単純化STUFFします。連結の最初のコンマが必要なため、実際にはその部分は必要ありません。したがって、それを削除する必要はありません。また、XML列(TYPE句付き)を強制的に変換するのはNVARCHAR

後で編集

免責事項:私はあなたのテーブル構造とデータを持っていなかったので、これはテストされていません

DECLARE @cols NVARCHAR(MAX),
        @query NVARCHAR(MAX), 
        @alter_query NVARCHAR(max);

SET @cols = 
        (
        SELECT   ',' + QUOTENAME(b."NewName")
        FROM    (
                    SELECT  myKey, 
                        win = SUM(win)
                    FROM    xxx.dbo.yyy
                    GROUP BY myKey
                    ) x
                    INNER JOIN #NameSwitch b ON
                        x.myKey = b.myKey
        ORDER BY x.win DESC
        FOR XML PATH('')
        ) -- this will render smth like ",col1,col2" 
SET @alter_query = 
        (
        SELECT   ';ALTER TABLE #XXX ADD ' + QUOTENAME(b."NewName") +' '+ QUOTENAME(b."ColType") +' NULL'
        FROM    (
                    SELECT  myKey, 
                        win = SUM(win)
                    FROM    xxx.dbo.yyy
                    GROUP BY myKey
                    ) x
                    INNER JOIN #NameSwitch b ON
                        x.myKey = b.myKey
        ORDER BY x.win DESC
        FOR XML PATH('')
        ) -- this will render smth like ";ALTER TABLE #XXX ADD col1 VARCHAR(MAX);ALTER ..." 

CREATE TABLE #XXX (Measure INT NULL)

EXEC sp_ExecuteSQL @alter_query

SET @query =    
    'INSERT INTO #XXX (Measure+'@Cols+') SELECT [Measure]' + @cols + ' 
    FROM  
        (
            SELECT  [NewName], [Measure], [Amount]
            FROM    #UnpivottedData x
        ) x
        PIVOT 
        (
            SUM(Amount)
            FOR [NewName] in (' + STUFF(@cols, 1, 1, '') + ') -- here you need the STUFF to remove the first comma
        ) p ';


EXEC sp_ExecuteSQL @Query

SELECT * from #XXX 
于 2013-02-19T14:58:21.820 に答える