取消透视 SQL 表中的所有列
Posted
技术标签:
【中文标题】取消透视 SQL 表中的所有列【英文标题】:Unpivot ALL Columns in a SQL Table 【发布时间】:2014-02-24 19:23:01 【问题描述】:我有一个包含 30 列的表,我想轻松地取消透视所有列。我知道我可以使用这个策略:
SELECT col, value
INTO New_Table
FROM
(SELECT * FROM Test_Data) p
UNPIVOT
(value FOR col IN (Column_Name1, Column_Name2... Column_Name30)) as unpvt
我的数据是这样进来的:
Column_Name1 Column_Name2 Column_Name3
Value11 Value21 Value31
Value12 Value22 Value32
Value13 Value23 Value33
这就是我想将它存储在新表中的方式:
New_Column1 New_cloumn2
Column_Name1 Value11
Column_Name1 Value12
Column_Name1 Value13
Column_Name2 Value21
...
但一定有比输入 30 个列名更简单的方法。
提前致谢。
【问题讨论】:
如果您遇到的情况是,实际上应该将 30 列都视为一列是有意义的,这表明您的数据模型首先是严重错误的。为什么应该有一种“更简单的方法”来解决你自己制造的问题? 输入 30 列有多难? @adrianm 30 列都是 32 个字符的代码 @Damien_The_Unbeliever 这是一个 Excel 电子表格的上传,其中每个列标题是一个问题代码,响应如下 是的。 SQL 数据库表与电子表格不同。试图将它们视为同一事物会导致(奇怪的)尝试不恰当地使用它们。此时要学习的主要内容(可能)是表示和存储是两个不同的东西。仅仅因为您在屏幕上看到网格并不意味着数据需要存储在网格中。 【参考方案1】:这似乎是一个损坏的数据模型,但您可以避免输入列列表。
您可以使用它来生成列列表:
SELECT name
FROM sys.columns
WHERE objecT_id = OBJECT_ID('Test_Data')
还有:
DECLARE @List VARCHAR(MAX) = STUFF((SELECT DISTINCT ',' + QUOTENAME(name)
FROM sys.columns
WHERE objecT_id = OBJECT_ID('Test_Data')
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)')
,1,1,'')
PRINT @List
然后您可以在动态 sql 语句中使用该列表:
DECLARE @List VARCHAR(MAX) = STUFF((SELECT DISTINCT ',' + QUOTENAME(name)
FROM sys.columns
WHERE objecT_id = OBJECT_ID('Test_Data')
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)')
,1,1,'')
,@sql VARCHAR(MAX)
SET @sql = 'SELECT col,value
INTO New_Table
FROM (SELECT * FROM Test_Data) p
UNPIVOT (value FOR col IN ('+@List+')) as unpvt
'
EXEC (@sql)
我建议在使用EXEC
之前使用PRINT (@sql)
以确保动态查询是您所追求的。
【讨论】:
以上是关于取消透视 SQL 表中的所有列的主要内容,如果未能解决你的问题,请参考以下文章