1

我有一个包含发货的表(SQL Server 2008),因此“阶段 0”表示“新发货”,连续阶段是发货跟踪的不同阶段。

我正在尝试旋转下表:

CREATE TABLE TableName
    ([ID] int, [IDShip] int, [Date] datetime, [Stage] int, [Arg] int)
;

INSERT INTO TableName
    ([ID], [IDShip], [Date], [Stage], [Arg])
VALUES
    (1, 1, '2013-10-03 08:36:00', 0, Null),
    (2, 1, '2013-10-03 08:37:25', 1, 1),
    (3, 2, '2013-10-03 08:38:25', 0, Null),
    (4, 1, '2013-10-03 08:39:25', 2, 1),
    (5, 2, '2013-10-03 08:40:25', 1, 3)
;

(“Arg”是 Stage0 的 ID。选择 * 将是:)

ID IDShip Date                Stage   Arg
1  1      2013-10-03 08:36:00     0  Null
2  1      2013-10-03 08:37:25     1     1
3  2      2013-10-03 08:38:25     0  Null
4  1      2013-10-03 08:39:25     2     1
5  2      2013-10-03 08:40:25     1     3

变成类似的东西:

ID0 IDShip DateShipment         ID1 DateFirstStage      ID2 DateSecondStage
1   1      2013-10-03 08:36:00  2   2013-10-03 08:37:25 4   2013-10-03 08:39:25    
3   2      2013-10-03 08:38:25  5   2013-10-03 08:40:25 

有什么帮助吗?谢谢

4

2 回答 2

1

结果比我希望的要混乱一些,但这里是:

SELECT MAX([0]) AS ID0,
    IDShip,
    (SELECT [Date] FROM TableName T1 WHERE T1.ID = MAX([0]) AND T1.IDShip = Y.IDShip) AS DateShipment,
    MAX([1]) AS ID1,
    (SELECT [Date] FROM TableName T2 WHERE T2.ID = MAX([1]) AND T2.IDShip = Y.IDShip) AS DateFirstStage,
    MAX([2]) AS ID2,
    (SELECT [Date] FROM TableName T3 WHERE T3.ID = MAX([2]) AND T3.IDShip = Y.IDShip) AS DateSecondStage
FROM
    (SELECT * FROM TableName
    PIVOT (MAX([ID]) FOR Stage IN ([0], [1], [2])) AS X) Y
GROUP BY IDShip

您首先将表格转换为 3 个阶段的 ID,然后选择每个阶段及其日期。

于 2013-10-03T11:00:11.197 回答
0

看来您需要同时旋转多个列。但是,标准 PIVOT 语法不支持多列旋转。您可以使用它来旋转其中一个列,然后使用这些作为查找值,通过一系列相关子查询拉取其他列值。

我的方法与@Szymon 的方法相似,除了我设法避免在外部查询中分组,尽管我在其他阶段让事情变得更加混乱。这是我的尝试:

SELECT
  IDShip,
  ID0,
  ID1,
  ID2,
  DateShipment    = (SELECT Date FROM TableName WHERE ID = p.ID0),
  DateFirstStage  = (SELECT Date FROM TableName WHERE ID = p.ID1),
  DateSecondStage = (SELECT Date FROM TableName WHERE ID = p.ID2)
FROM (
  SELECT
    ID,
    IDShip,
    StageID = 'ID' + CAST(Stage AS varchar(10))
  FROM TableName
) AS s
PIVOT (
  MAX(ID) FOR StageID IN (ID0, ID1, ID2)
) AS p
;

使用适当的索引,它可能不会太糟糕,尽管您也可以尝试这种替代方法,它使用旧的旋转技术,使用条件聚合进行分组:

SELECT
  IDShip,
  ID0 = MAX(CASE Stage WHEN 0 THEN ID END),
  ID1 = MAX(CASE Stage WHEN 1 THEN ID END),
  ID2 = MAX(CASE Stage WHEN 2 THEN ID END),
  DateShipment    = MAX(CASE Stage WHEN 0 THEN Date END),
  DateFirstStage  = MAX(CASE Stage WHEN 1 THEN Date END),
  DateSecondStage = MAX(CASE Stage WHEN 2 THEN Date END)
FROM TableName
GROUP BY IDShip
;

这个 SQL Fiddle 演示将让您尝试这两种解决方案。

于 2013-10-04T13:04:25.830 回答