【问题标题】:Teradata partitioning sequential eventsTeradata 分区顺序事件
【发布时间】:2016-03-18 23:23:56
【问题描述】:

Teradata - 下面是两辆火车到达车站。 773 被清空(RI/RE)然后加载(RI/RL)然后离开 TD。 819 只清空然后离开。我想在此表下方创建结果。我试过在汽车上使用案例语句分组,但同一辆车有多次通过车站的行程,所以 max 和 min 给了我不可预测的结果。我已经阅读了分区,但我很难想象这一点。任何帮助表示赞赏。

*注意:最好将初始搜索限制为 EVT_CD='TA' AND STN=DEST 以消除任何简单通过车站的汽车。但我不能将整个记录集限制在此范围内,因为 TD 有不同的目的地。

CAR_NUMB    EVT_DT  EVT_TM  EVT_CD  EVST_CD WB_ID   STN     DEST
773 03/08/2016  19.05.00    TA          582016  BOSTON      BOSTON  
773 03/12/2016  04.04.00    AP  PU      582016  BOSTON      BOSTON  
773 03/12/2016  14.35.00    RI  RE      412016  BOSTON      BOSTON  
773 03/12/2016  14.37.00    AP  PL      412016  BOSTON      BOSTON  
773 03/12/2016  14.45.00    RI  RL      812016  BOSTON      HOUSTON 
773 03/14/2016  12.22.00    TD          812016  BOSTON      HOUSTON 
819 03/04/2016  17.50.00    TA          362016  STLOUIS     STLOUIS  
819 03/06/2016  13.50.00    AP  PU      362016  STLOUIS     STLOUIS  
819 03/06/2016  17.27.55    RI  RE      042016  STLOUIS     STLOUIS  
819 03/07/2016  00.37.00    RI  PR      042016  STLOUIS     PORTLAND
819 03/11/2016  01.47.00    TD          042016  STLOUIS     PORTLAND     

Desired output: 
CAR_NUMB    TA              AP          RIRE        RIRL        TD
773 03/08/2016 19.05.00 03/12/20..  03/12/20..  03/12/20..  03/14/2016  12.22.00
819 03/04/2016 17.50.00 03/06/20..  03/06/20..      null    03/11/2016 01.47.00

上面的 [..]。我切断了格式化的时间戳。

【问题讨论】:

  • 您的 Teradata 版本是什么? “同一辆车有多次经过车站的行程” = 同一个 CAR_NUMB/DEST 组合可能还有另一组行? TA 和 TD 之间的最大行数是多少
  • 发布:15.00.0501 15.00.05.01。是的,一辆车可能会从波士顿到休斯顿再回来很多次。有时往返需要 7 天或 2 个月,因此 car/dest 组合(这是我一直在使用的结合手动纠错的组合)在足够长的时间内失败,成为问题。如果一周前发生 TD 事件,则使用带有 evt 日期的 Max 聚合可以产生汽车在到达之前离开院子。

标签: teradata partition


【解决方案1】:

您可以使用窗口聚合函数使用CASE 在接下来的 5 行中搜索给定 EVT_CD 的最短日期/时间。

我将日期和时间与时间戳结合起来,因为它更易于使用:

SELECT tab.*
  ,CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND) AS TA
  ,MIN(CASE WHEN EVT_CD = 'AP'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) 
   OVER (PARTITION BY CAR_NUMB
         ORDER BY EVT_DT, EVT_TM
         ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) AS AP
  ,MIN(CASE WHEN EVT_CD = 'RI' AND EVST_CD = 'RE'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) 
   OVER (PARTITION BY CAR_NUMB 
         ORDER BY EVT_DT, EVT_TM
         ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) AS RIRE
  ,MIN(CASE WHEN EVT_CD = 'RI' AND EVST_CD = 'RL'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) 
   OVER (PARTITION BY CAR_NUMB 
         ORDER BY EVT_DT, EVT_TM
         ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) AS RIRL
  ,MIN(CASE WHEN EVT_CD = 'TD'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) 
   OVER (PARTITION BY CAR_NUMB 
         ORDER BY EVT_DT, EVT_TM
         ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING) AS TD
FROM tab
QUALIFY -- finally return only the starting row
   EVT_CD = 'TA'

如果TA 和TD 之间的行数可以大于5,则必须相应地调整ROWS。如果数字变化很大并且缺少EVT_CD,则此方法可能会失败并报告下一次行程的数据。这个问题可以通过添加另一个步骤来解决:

SELECT 
   CAR_NUMB
  ,TA
  ,CASE WHEN   AP < TD THEN AP END AS AP
  ,CASE WHEN RIRE < TD THEN RIRE END AS RIRE
  ,CASE WHEN RIRL < TD THEN RIRL END AS RIRL
  ,TD
FROM
 (
   previous query
 ) AS dt

如果TD 可能丢失,您可以采用不同的方法:找到之前的TA 时间戳并按其分组:

SELECT 
   CAR_NUMB
  ,TA
  ,MIN(CASE WHEN EVT_CD = 'AP'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) AS AP
  ,MIN(CASE WHEN EVT_CD = 'RI' AND EVST_CD = 'RE'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) AS RIRE
  ,MIN(CASE WHEN EVT_CD = 'RI' AND EVST_CD = 'RL'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) AS RIRL
  ,MIN(CASE WHEN EVT_CD = 'TD'
            THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
       END) AS TD
FROM
 (
   SELECT tab.*
     ,MAX(CASE WHEN EVT_CD = 'TA'
               THEN CAST(EVT_DT AS TIMESTAMP(0)) + (EVT_TM - TIME '00:00:00' HOUR TO SECOND)
          END) 
      OVER (PARTITION BY CAR_NUMB
            ORDER BY EVT_DT, EVT_TM
            ROWS UNBOUNDED PRECEDING) AS TA
   FROM tab
   -- maybe QUALIFY TA IS NOT NULL?
 ) AS dt
GROUP BY
   CAR_NUMB
  ,TA

【讨论】:

  • 谢谢dnoeth,你真棒。我今天会玩这个,看看我能不能让它工作。为简洁起见,我确实简化了上面的示例数据。实际上,TA 和 TD 之间可能有 20-30 个事件。开关、跟踪命令等。最后,我可能不得不使用脚本循环来强制执行此操作,但我将首先尝试使用旧学院的分区。这真的很有帮助。再次感谢。
  • P.S.我试图对此表示赞成,但我还没有足够的代表点数。所以请给读到这篇文章的人点赞。
  • @CalHarris:第二个查询应该适用于两个TA之间的任意组合/行数...
猜你喜欢
  • 2018-09-09
  • 2023-04-07
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
  • 2014-12-08
相关资源
最近更新 更多