【问题标题】:How to pivot a dates table in SQL Server?如何在 SQL Server 中旋转日期表?
【发布时间】:2021-08-18 17:44:14
【问题描述】:

我有一个有很多日期的containerID 号码。我已使用下面的代码将每个日期转换为一列。问题是每一列都有一组三个空值。我正在尝试将我的四行相同容器 ID 合并为一行,其中四列上有日期。

示例数据:

    ContainerID MovementMilestone   MilestoneDate
    ---------------------------------------------
    ACCU4035970 Left Yard           2021-02-01
    ACCU4035970 Empty Return        2021-02-01
    ACCU4035970 Yard Arrival        2021-01-29
    ACCU4035970 Gate Out            2021-01-29

代码:

SELECT
    ContainerID,
    CASE WHEN MovementMilestone = 'Gate Out' THEN MilestoneDate END AS 'mm_GateOut',
    CASE WHEN MovementMilestone = 'Yard Arrival' THEN MilestoneDate END AS ' mm_YardArrival',
    CASE WHEN MovementMilestone = 'Left Yard' THEN MilestoneDate END AS 'mm_LeftYard',
    CASE WHEN MovementMilestone = 'Empty Return' THEN MilestoneDate END AS 'mm_EmptyReturn'
FROM 
    #movementmilestone

输出:

   ContainerID  mm_GateOut   mm_YardArrival mm_LeftYard mm_EmptyReturn
   ------------------------------------------------------------------------
   ACCU4035970  NULL         NULL           2021-02-01  NULL
   ACCU4035970  NULL         NULL           NULL        2021-02-01
   ACCU4035970  NULL         2021-01-29     NULL        NULL
   ACCU4035970  2021-01-29   NULL           NULL        NULL

我知道 SQL Server 上的 PIVOT 功能,但以下来自 Internet 的示例使我明白了这一点:

SELECT *
FROM
    (SELECT
         containerID,
         MovementMilestone,
         MilestoneDate
     FROM 
         #movementmilestone) AS #source
PIVOT 
    (MAX(MilestoneDate) FOR [MovementMilestone]
     IN ([GateOut], [YardArrival], [LeftYard], [EmptyReturn]))
    AS #alias

输出:

   ContainerID  GateOut YardArrival LeftYard    EmptyReturn
   ACCU4035970  NULL    NULL        NULL        NULL

感谢您的帮助!

【问题讨论】:

  • 更改枢轴上的 IN 并添加空格。 MovementMilestone 中的值将是列名。所以改成IN ([Gate Out], [Yard Arrival], [Left Yard], [Empty Return])
  • 感谢 Tim Mylott 和 GrahamH,他们都解决了我的问题。

标签: sql-server pivot pivot-table


【解决方案1】:
--OLD FASHIONED WAY <GRIN>

CREATE TABLE #movementmilestone(
   ContainerID       VARCHAR(30) NOT NULL
  ,MovementMilestone VARCHAR(11) NOT NULL
  ,MilestoneDate     DATE  NOT NULL
 );
INSERT INTO #movementmilestone(ContainerID,MovementMilestone,MilestoneDate) VALUES ('ACCU4035970','Left','2021-02-01');
INSERT INTO #movementmilestone(ContainerID,MovementMilestone,MilestoneDate) VALUES ('ACCU4035970','Empty','2021-02-01');
INSERT INTO #movementmilestone(ContainerID,MovementMilestone,MilestoneDate) VALUES ('ACCU4035970','Yard','2021-01-29');
INSERT INTO #movementmilestone(ContainerID,MovementMilestone,MilestoneDate) VALUES ('ACCU4035970','Gate','2021-01-29');


SELECT
       ContainerID,
       MAX( CASE WHEN MovementMilestone = 'Gate' THEN MilestoneDate END ) AS 'mm_GateOut',
       MAX (CASE WHEN MovementMilestone = 'Yard' THEN MilestoneDate END ) AS ' mm_YardArrival',
       MAX( CASE WHEN MovementMilestone = 'Left' THEN MilestoneDate END ) AS 'mm_LeftYard',
       MAX ( CASE WHEN MovementMilestone = 'Empty' THEN MilestoneDate END ) AS 'mm_EmptyReturn'
    FROM #movementmilestone
    GROUP BY ContainerID

【讨论】:

    【解决方案2】:

    您的pivot 查询的唯一问题是您没有在IN 子句中提供正确的列名。

    尝试以下方法:

    select ContainerID, [Gate Out] as mm_GateOut, [Yard Arrival] as mm_YardArrival, [Left Yard] as mm_LeftYard, [Empty Return] as mm_EmptyReturn
    from 
    (
        select ContainerID, MovementMilestone, MilestoneDate
        from movementmilestone
    )t
    pivot
    (
        max(MilestoneDate)
        for MovementMilestone in ([Left Yard], [Empty Return], [Yard Arrival], [Gate Out])
    )pvt;
    

    请看 dbfiddle here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      相关资源
      最近更新 更多