SQL Server 转置数据 - 可能进行数据透视?
Posted
技术标签:
【中文标题】SQL Server 转置数据 - 可能进行数据透视?【英文标题】:SQL Server Transpose Data - Pivot Possibly? 【发布时间】:2014-04-01 18:04:11 【问题描述】:我一直在寻找一种解决方案,通过元数据查找表将系统中的源数据转换为目标表。我需要一种将源数据转置/转置为列(由各种数据类型组成)的方法。每列的数据类型都列在元数据表中。
表名:SRC
SrcID AGE City Date
------------------------------------
01 32 London 01-01-2013
02 35 Lagos 02-01-2013
03 36 NY 03-01-2013
表名:Metadata
MetaID Column_Name Column_type
-------------------------------------------------
11 AGE col_integer
22 City col_character
33 Date col_date
目标表:
要加载到目标表中的源数据(如下图):
目标表:
SrcID MetaID col_int col_char col_date
---------------------------------------------------------
01 11 32 - -
01 22 - London -
01 33 - - 01-01-2013
02 11 35 - -
02 22 - Lagos -
02 33 - - 02-01-2013
03 11 36 - -
03 22 - NY -
03 33 - - 03-01-2013
任何帮助将不胜感激。
谢谢,
【问题讨论】:
【参考方案1】:下面给出的示例查询和步骤。
select srcid, metaid, col_integer, col_character,col_date
from
(
select SrcId,
CAST(AGE AS NVARCHAR(MAX)) AS AGE,
CAST(City AS NVARCHAR(MAX)) AS City,
CAST([Date] AS NVARCHAR(MAX)) AS [Date]
from src
) as dat
unpivot
(
ColVal for Columz IN (AGE, City, [Date])
) as upiv
left join metadata as m
on upiv.Columz = m.Column_name
pivot(
max(ColVal)
for Column_type in ([col_integer], [col_character], [col_date])
) as piv1
用于测试这些查询的示例 SQL 小提琴(适用于 SQL 2008 或更高版本)- http://sqlfiddle.com/#!3/e5e38b/1
如果你想学习,下面给出的步骤 -
第 1 步 -
希望我们可以将 SRC 的年龄列加入元的年龄行。因此,我们使用 unpivot 将 SRC 列转换为行。
select *
from
(
-- Unpivot query. You need to cast it,
-- otherwise you get an error
select SrcId,
CAST(AGE AS NVARCHAR(MAX)) AS AGE,
CAST(City AS NVARCHAR(MAX)) AS City,
CAST([Date] AS NVARCHAR(MAX)) AS [Date]
from src
) as dat
unpivot
(
ColVal for Columz IN (AGE, City, [Date])
) as upiv
注意 - 我们为什么要投射?参考这个-UNPIVOT on Table in a Different Server/Database Fails with 'conflicts with the type of other columns' error
输出 -
SrcId, ColVal, Columz
1,32,AGE
1,London,City
1,2013-01-01,Date
2,35,AGE
2,Lagos,City
2,2013-02-01,Date
3,36,AGE
3,NY,City
3,2013-03-01,Date
第 2 步 -
现在我们准备好加入元数据表了。我们只需添加以下连接 到上面的代码 -
left join metadata as m
on upiv.Columz = m.Column_name
输出 -
SrcId,ColVal,Columz,MetaId,Column_Name,Column_Type
1,32,AGE,11,AGE,col_integer
1,London,City,22,City,col_character
1,2013-01-01,Date,33,Date,col_date
2,35,AGE,11,AGE,col_integer
2,Lagos,City,22,City,col_character
2,2013-02-01,Date,33,Date,col_date
3,36,AGE,11,AGE,col_integer
3,NY,City,22,City,col_character
3,2013-03-01,Date,33,Date,col_date
第 3 步 -
我们现在看到我们希望根据您的需要将 Column_Type 列中的那些行转换为列。所以我们使用 PIVOT。我们在上面的代码中加入如下代码
pivot(
max(ColVal)
for Column_type in ([col_integer], [col_character], [col_date])
) as piv1
输出 -
SrcId,Columz,MetaId,Column_Name,col_integer,col_character,col_date
1,AGE,11,AGE,32,NULL,NULL
1,City,22,City,NULL,London,NULL
1,Date,33,Date,NULL,NULL,2013-01-01
2,AGE,11,AGE,35,NULL,NULL
2,City,22,City,NULL,Lagos,NULL
2,Date,33,Date,NULL,NULL,2013-02-01
3,AGE,11,AGE,36,NULL,NULL
3,City,22,City,NULL,NY,NULL
3,Date,33,Date,NULL,NULL,2013-03-01
第 4 步 -
此结果有一些额外的列。要删除多余的列,请将STEP 1
中的第一行更改为select *
,即select srcid, metaid, col_integer, col_character,col_date
【讨论】:
以上是关于SQL Server 转置数据 - 可能进行数据透视?的主要内容,如果未能解决你的问题,请参考以下文章