如何在连接多个必须是 PIVOT 的表时创建临时表
Posted
技术标签:
【中文标题】如何在连接多个必须是 PIVOT 的表时创建临时表【英文标题】:how to create temp table while Joining multiple tables that have to be PIVOT 【发布时间】:2013-04-02 05:36:22 【问题描述】:我对不同的表有类似的 3-4 个脚本来动态 PIVOT,如先前发布的那样 Dynamic Pivot (row to columns)
目标: - 创建一个 excel 文件连接 PIVOTed 表中的所有字段(每个表中的所有行)
步骤:
为每个集合创建单独的临时表(在不同表上进行透视之后)
JOIN 列 ID 上的所有临时表
从结果集中选择列(所有临时表)
**想知道是否有更好的方法来创建临时表,该方法使用连接所有表以进行最终选择的过程。
**我尝试创建临时表但收到错误:无效对象
由于上一篇文章中接受的答案**
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:OurTable的相同代码PIVOT**
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
【问题讨论】:
你能把你试过的完整代码贴出来吗?还尝试修改上一个问题中的working demo 来解释您的问题。这将非常有帮助。#t1
、#t2
和 #t3
是否已定义?还是您要创建临时表?
不,它们不能更早地定义,因为它们取决于每个 Pivot 案例的动态结果集。我正在尝试将每个 Pivot 结果保存到它们各自的临时表中。我没有使用表变量。
【参考方案1】:
您的部分问题是您正在使用动态 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。
这将允许您将多个表连接在一起。
参考:
Temporary Tables in SQL Server【讨论】:
非常感谢您在这里展示了全局临时表的使用。在我看到这个解决方案之前,我刚刚添加了: set @query = 'select * into #temp1 ... 最后我添加到 stmt ' drop table T1; select * into T1 from #temp1;'它实际上创建了一个表。但看起来我将继续使用实际表格,因为它们将用于报告目的。再次感谢您帮助我解决此问题。 @Rodricks 是的,创建一个表而不是一个临时表可能会更好。很高兴你成功了。 我在另一个表sqlfiddle.com/#!3/100bd/5 上尝试了上述方法,但无法正常工作,我不断收到语法错误。以上是关于如何在连接多个必须是 PIVOT 的表时创建临时表的主要内容,如果未能解决你的问题,请参考以下文章