Unpivot表,其中包含不同行中的值

时间:2017-11-22 19:45:48

标签: sql-server

我有一个表,其中一列让我们说col_val包含一次操作描述和一次该操作的时间值。 E.G。

MachineXYZ, SerialNo
MachineXYZ, Action1 Desc
MachineXYZ, Action1 Time
MachineXYZ, Action2 Desc
MachineXYZ, Action2 Time
...

我需要将其取消以便获得:

MachineXYZ, Action1 Desc, Action1 Time
MachineXYZ, Action2 Desc, Action2 Time

...

有什么建议吗?我之前从未使用过unpivot。 非常感谢您的建议。

1 个答案:

答案 0 :(得分:0)

这可能不是您正在寻找的,因为我没有使用unpivot作为答案。鉴于您的资产表和事务表的示例,我决定使用rank来为每台机器选择前两个事务。如果您想要最后两个动作,可以将等级顺序更改为desc。

DECLARE @machine TABLE
      (
          machineName  VARCHAR(50)
        , serialNumber VARCHAR(50)
      );

INSERT INTO @machine
     (
         machineName
       , serialNumber
     )
VALUES
     ('ABC', '1234')
   , ('XYZ', '4321')
   , ('YYZ', '2112');

DECLARE @machineAction TABLE
      (
          machineName   VARCHAR(50)
        , machineAction VARCHAR(50)
        , actionTime    TIME
      );

INSERT INTO @machineAction
     (
         machineName
       , machineAction
       , actionTime
     )
VALUES
     ('XYZ', 'Installed', '22:50:07')
   , ('XYZ', 'Replaced', '23:44:22')
   , ('ABC', 'Installed', '05:11:01')
   , ('YYZ', 'Installed', '02:50:07')
   , ('YYZ', 'Replaced', '06:44:22')
   , ('YYZ', 'Removed', '10:33:12');

WITH cte_actionRank
    AS (
           SELECT ma.machineName
                , ma.machineAction
                , ma.actionTime
                , seq = RANK() OVER (PARTITION BY ma.machineName ORDER BY ma.actionTime)
             FROM @machineAction AS ma
       )
SELECT machine     = m.machineName
     , m.serialNumber
     , action1     = a1.machineAction
     , action1Time = a1.actionTime
     , action2     = a2.machineAction
     , action2Time = a2.actionTime
  FROM @machine                      AS m
      LEFT OUTER JOIN cte_actionRank AS a1
          ON m.machineName = a1.machineName
             AND a1.seq = 1
      LEFT OUTER JOIN cte_actionRank AS a2
          ON a1.machineName = a2.machineName
             AND a2.seq = 2;