Rodricks
Rodricks

Reputation: 107

how to create temp table while Joining multiple tables that have to be PIVOT

I have similar 3-4 scripts for different tables to dynamically PIVOT as previously posted Dynamic Pivot (row to columns)

Goals: - Create a excel file Joining all the fields from the PIVOTed tables(all the rows from each table)

Steps:

**Would like to know if there is a better way to create a temp table using a procedure for joining all the tables for the final select.

**I tried creating temp table but got the error :invalid object

as a result of the accepted answer in the previous post**

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

**


Case 1: Pivot on yourtable

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)

I tried creating temp table but got the error :invalid object as a result of the accepted answer in the previous post

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

Case 2: Same code PIVOT for MYtable

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

** Case 3:Same code 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

FINAL SELECT:

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

Upvotes: 0

Views: 6221

Answers (1)

Taryn
Taryn

Reputation: 247670

Part of your problem is that you are using dynamic sql and you want to insert that into a temp table for use later on. Here are the issues with that:

  • The temp table cannot be created before because the number of columns is unknown.
  • A temp table created inside the dynamic SQL will be out of scope for use after. This issue exists when you create a local temp table (those that begin with a single # sign)

If you want to join these multiple tables together than you could create a global temp table or a real table (not temp) that can be created in during the dynamic SQL execution and used outside of that scope.

Using the code from the OP I altered it with a table being created:

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

See SQL Fiddle with Demo.

This will allow you to join the multiple tables together.

Reference:

Upvotes: 2

Related Questions