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

尝试更改包括 into 子句

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

这将为结果创建临时表...

如果你真的想在选择之前创建..

您需要收集列的类型来构建创建表语句..

于 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);

附言

  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 回答