Pivot / Unpivot和排序配对数据

时间:2017-06-12 08:54:25

标签: sql-server tsql pivot unpivot

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

SELECT TOP 1
    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
FROM 
    Telephone_Numbers

返回

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  111111111   2015-06-22  222222222   2015-02-22  333333333   2017-01-25  444444444   2016-02-12  555555555   2015-06-13  666666666   2017-05-18  777777777   2016-12-23  888888888   2016-01-11  999999999

但我在追求

ID  Type    Date_Changed    Tel_Number  Rank
23  Home    2016-11-25  111111111   1
23  Home    2015-06-22  222222222   2
23  Home    2015-02-22  333333333   3
23  Work    2017-01-25  444444444   1
23  Work    2016-02-12  555555555   2
23  Work    2015-06-13  666666666   3
23  Mobile  2017-05-18  777777777   1
23  Mobile  2016-12-23  888888888   2
23  Mobile  2016-01-11  999999999   3

非常感谢帮助

2 个答案:

答案 0 :(得分:2)

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

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

示例

auto s = std::make_shared<std::string>("payload");

答案 1 :(得分:0)

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

作为一般规则:
每当您想要创建包含其名称索引的列(例如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。所以可能有一张人员表。现在你需要这样的东西:

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

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