如何在连接多个必须为PIVOT的表时创建临时表

时间:2013-04-02 05:36:23

标签: sql sql-server sql-server-2008-r2 pivot

我有类似的3-4个脚本,用于不同的表,以便像以前发布的那样动态PIVOT Dynamic Pivot (row to columns)

目标:   - 创建一个excel文件加入PIVOTed表中的所有字段(每个表中的所有行)

步骤:

  • 为每个集创建单独的临时表(在不同表上进行透视后)

  • 加入列ID

  • 上的所有临时表
  • 从结果集中选择SELECT列(所有临时表)

**想知道是否有更好的方法来创建临时表,使用一个过程来连接最终选择的所有表。

**我尝试创建临时表但得到错误:无效对象

由于上一篇文章中接受的回答**

INSERT into #T1 execute('execute' + @query )
select * from #T1

**


案例1:透视您的

DECLARE @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT ',' 
                      + quotename('Instance'+ cast(instance as varchar(10))+'_'+c.name)
                    from yourtable t
                    cross apply sys.columns as C
                    where C.object_id = object_id('yourtable') and
                         C.name not in ('id', 'instance')
                    group by t.instance, c.name
                    order by t.instance
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select *
      from
      (
        select id, 
          ''Instance''+cast(instance as varchar(10))+''_''+col col, 
          value
        from 
        (
          select id, 
            Instance, 
            Name, 
            cast(Size as varchar(50)) Size,
            Tech
          from yourtable
        ) x
        unpivot
        (
          value
          for col in (Name, Size, Tech)
        ) u 
      ) x1
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'

--exec(@query)

我尝试创建临时表但得到错误:无效对象 由于上一篇文章中接受的答案

INSERT into #T1 execute('execute' + @query )
select * from #T1

案例2:MYtable的相同代码PIVOT

DECLARE @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT ',' 
                      + quotename('Instance'+ cast(instance as varchar(10))+'_'+c.name)
                    from mytable t
                    cross apply sys.columns as C
                    where C.object_id = object_id('yourtable') and
                         C.name not in ('id', 'instance')
                    group by t.instance, c.name
                    order by t.instance
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select *
      from
      (
        select id, 
          ''Instance''+cast(instance as varchar(10))+''_''+col col, 
          value
        from 
        (
          select id, 
            Instance, 
            Name, 
            cast(Size as varchar(50)) Size,
            Tech
          from mytable
        ) x
        unpivot
        (
          value
          for col in (Name, Size, Tech)
        ) u 
      ) x1
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'


    INSERT into #T2 execute('execute' + @query2 )
    select * from #T2

**案例3:相同的代码PIVOT for OurTable **

DECLARE @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT ',' 
                      + quotename('Instance'+ cast(instance as varchar(10))+'_'+c.name)
                    from ourtable t
                    cross apply sys.columns as C
                    where C.object_id = object_id('yourtable') and
                         C.name not in ('id', 'instance')
                    group by t.instance, c.name
                    order by t.instance
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select *
      from
      (
        select id, 
          ''Instance''+cast(instance as varchar(10))+''_''+col col, 
          value
        from 
        (
          select id, 
            Instance, 
            Name, 
            cast(Size as varchar(50)) Size,
            Tech
          from ourtable
        ) x
        unpivot
        (
          value
          for col in (Name, Size, Tech)
        ) u 
      ) x1
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'


   INSERT into #T3 execute('execute' + @query2 )
    select * from #T3

最终选择:

select * from #T1
inner join #T1.id=#T2.id
inner join #T1.id=#T3.id

1 个答案:

答案 0 :(得分:2)

您的部分问题是您正在使用动态SQL,并且您希望将其插入临时表以供以后使用。以下是问题:

  • 之前无法创建临时表,因为列数未知。
  • 在动态SQL中创建的临时表将超出使用范围。创建本地临时表(以单个#符号开头的那些)时存在此问题

如果要将这些多个表连接在一起,则可以创建一个全局临时表或真实表(非临时),这些表可以在动态SQL执行期间创建并在该范围之外使用。

使用OP中的代码我将其更改为正在创建的表:

DECLARE @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT ',' 
                      + quotename('Instance'+ cast(instance as varchar(10))+'_'+c.name)
                    from yourtable t
                    cross apply sys.columns as C
                    where C.object_id = object_id('yourtable') and
                         C.name not in ('id', 'instance')
                    group by t.instance, c.name
                    order by t.instance
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select *
     into ##t1  -- < create global temp table or real table without the ##
      from
      (
        select id, 
          ''Instance''+cast(instance as varchar(10))+''_''+col col, 
          value
        from 
        (
          select id, 
            Instance, 
            Name, 
            cast(Size as varchar(50)) Size,
            Tech
          from yourtable
        ) x
        unpivot
        (
          value
          for col in (Name, Size, Tech)
        ) u 
      ) x1
      pivot
      (
        max(value)
        for col in ('+ @colspivot +')
      ) p'

exec(@query);

select * from ##t1

请参阅SQL Fiddle with Demo

这将允许您将多个表连接在一起。

参考: