【问题标题】:SQL Server Transpose Data - Pivot Possibly?SQL Server 转置数据 - 可能进行数据透视?
【发布时间】: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

任何帮助将不胜感激。

谢谢,

【问题讨论】:

    标签: sql sql-server pivot transpose unpivot


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多