【问题标题】:Pivot/Unpivot and Ranking paired dataPivot/Unpivot 和 Ranking 配对数据
【发布时间】:2017-06-12 08:54:24
【问题描述】:

在每行有 9 个匹配对的表中,是否可以使用 Pivot 生成列,例如以下内容:

选择前 1 ID, HOME_APPDTE1, 家庭号码 1, HOME_APPDTE2, 家庭号码 2, HOME_APPDTE3, 家庭编号 3, WORK_APPDTE1, 工作编号2, WORK_APPDTE2, 工作编号 3, WORK_APPDTE3, 工作编号 1, MOBILE_APPDTE1, 手机号码1, MOBILE_APPDTE2, 手机号码2, MOBILE_APPDTE3, 手机号码3 从 电话号码

返回

ID HOME_APPDTE1 HOMENUMBER1 HOME_APPDTE2 HOMENUMBER2 HOME_APPDTE3 HOMENUMBER3 WORK_APPDTE1 WORKNUMBER2 WORK_APPDTE2 WORKNUMBER3 WORK_APPDTE3 WORKNUMBER1 MOBILE_APPDTE1 MOBILENUMBER1 MOBILE_APPDTE2 MOBILENUMBER2 MOBILE_APPDTE3 MOBILENUMBER3 23 2016年11月25日2015年6月22日111111111 222222222 2015年2月22日2017年1月25日333333333 444444444 2016年2月12日2015年6月13日555555555 666666666 2017年5月18日2016年12月23日777777777 888888888 2016 -01-11 999999999

但我在追求

ID 类型 Date_Changed Tel_Number 等级 23 首页 2016-11-25 111111111 1 23 首页 2015-06-22 222222222 2 23 首页 2015-02-22 333333333 3 23 工作 2017-01-25 444444444 1 23 工作 2016-02-12 555555555 2 23 工作 2015-06-13 666666666 3 23 手机 2017-05-18 777777777 1 23 手机 2016-12-23 888888888 2 23 手机 2016-01-11 999999999 3

在此先感谢您的帮助

【问题讨论】:

    标签: sql-server tsql pivot unpivot


    【解决方案1】:

    假设您不需要动态,另一种选择是使用 CROSS APPLY

    另外,假设您不需要动态解决方案。

    示例

    Select A.ID
          ,B.*
     From  YourTable A
     Cross Apply ( values ('Home'  ,HOME_APPDTE1  ,HOMENUMBER1  ,1)
                         ,('Home'  ,HOME_APPDTE2  ,HOMENUMBER2  ,2)
                         ,('Home'  ,HOME_APPDTE3  ,HOMENUMBER3  ,3)
                         ,('Work'  ,WORK_APPDTE1  ,WORKNUMBER1  ,1)
                         ,('Work'  ,WORK_APPDTE2  ,WORKNUMBER2  ,2)
                         ,('Work'  ,WORK_APPDTE3  ,WORKNUMBER2  ,3)
                         ,('Mobile',MOBILE_APPDTE1,MOBILENUMBER1,1)
                         ,('Mobile',MOBILE_APPDTE2,MOBILENUMBER2,2)
                         ,('Mobile',MOBILE_APPDTE3,MOBILENUMBER3,3)
                 ) B ([Type],[DateChanged],[Tel_Number],[Rank])
    

    【讨论】:

    • 感谢@John,这是我回答的基础。
    • @MarkHedley 很高兴它有帮助
    【解决方案2】:

    这是一个非常糟糕的设计...我希望您需要这个来解决这个问题...

    作为一般规则:
    每当您想创建对其名称有索引的列时(例如 Date1Date2),这清楚地表明您需要一个相关的边表!

    你可以试试这样的:

    DECLARE @mockup TABLE(ID INT,HOME_APPDTE1 DATE,HOMENUMBER1 VARCHAR(100)
                                ,HOME_APPDTE2 DATE,HOMENUMBER2 VARCHAR(100)
                                ,HOME_APPDTE3 DATE,HOMENUMBER3 VARCHAR(100)
                                ,WORK_APPDTE1 DATE,WORKNUMBER1 VARCHAR(100) 
                                ,WORK_APPDTE2 DATE,WORKNUMBER2 VARCHAR(100));
    
    SET DATEFORMAT ymd;
    INSERT INTO @mockup VALUES
     (23,'2014-11-25','111111111'
        ,'2011-05-03','222222222'
        ,'2015-12-12','333333333'
        ,'2014-04-02','444444444'
        ,'2014-02-24','555555555');
    
    WITH Normalized AS
    (
                  SELECT ID,'Home' AS [Type],HOME_APPDTE1 AS DateChanged,HOMENUMBER1 AS Tel_Number,1 AS [Rank] FROM @mockup
        UNION ALL SELECT ID,'Home',HOME_APPDTE2,HOMENUMBER2,2 FROM @mockup
        UNION ALL SELECT ID,'Home',HOME_APPDTE3,HOMENUMBER3,3 FROM @mockup
        UNION ALL SELECT ID,'Work',WORK_APPDTE1,WORKNUMBER1,1 FROM @mockup
        UNION ALL SELECT ID,'Work',WORK_APPDTE2,WORKNUMBER2,2 FROM @mockup
    )
    SELECT *
    FROM Normalized
    ORDER BY ID,[Type],[Rank];
    

    你应该做什么:

    Telephone_Numbers 表中的 ID 可以假定为一个人的 ID。所以可能有一个persons表。现在你需要这样的东西:

    • phone_type 目录
    • phone_number 表,您需要的地方
      • PhoneID (PK), OwnerID (FK), PhoneTypeID (FK), ChangeDate and Number。如果排名不是从更改日期的顺序中获取的,您可能需要一个 Rank 列...

    实际上,您尝试实现的目标结构大致是您实际应该如何存储数据的结构......

    【讨论】:

    • 感谢您的及时回复 Shnugo,我同意“您尝试实现的目标结构大致是您实际存储数据的结构”但不幸的是,源数据来自我们与之合作的第三方对改变结构没有影响。
    • @MarkHedley,好吧,运气不好...希望我的回答能帮助您解决这个问题...
    猜你喜欢
    • 1970-01-01
    • 2016-02-21
    • 2019-09-25
    • 1970-01-01
    • 2021-06-13
    • 2022-01-11
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多