我一直在寻找一种解决方案,通过元数据查找表将源数据从系统转换为目标表。我需要一种将源数据转置/转换为列(通过各种数据类型)的方法。每列的数据类型都列在元数据表中。
表名: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
非常感谢任何帮助。
谢谢,
答案 0 :(得分:0)
下面给出的示例查询和步骤。
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小提琴来测试这些查询(它适用于SQLs 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