提取给定状态代码 Teradata 的状态开始日期和更改日期

问题描述 投票:0回答:1

我有以下格式的数据,其中包含几个状态代码及其日期。有问题的代码是 3 和 8。我需要找到

STcode=3/8
的开始日期并将其用作
STDATE
,如果
STCODE
更改为 3/8 以外的其他时间,那么它将成为我的
ENDDATE

在以下示例中,ID 101 在

STCODE=3
首次进入
10/21/2022
,并在
6
将其状态更改为
10/26/2022
。再次在
10/26/2022
,它位于
STCODE=3
,更改日期为
10/27/2022
。我需要在输出中将它们作为两个单独的记录

   ID         STCODE                 DATE
  101         3                     10/21/2022
  101         3                     10/22/2022
  101         3                     10/23/2022
  101         6                     10/25/2022
  101         3                     10/26/2022
  101         7                     10/27/2022
  102         8                     10/25/2022
  102         5                     10/26/2022

想要

    ID           STDATE              ENDDATE
    101        10/21/2022            10/25/2022
    101        10/26/2022            10/27/2022
    102        10/25/2022            10/26/2022
  

我尝试了类似的方法,但没有产生任何预期的结果

  WITH STS AS (
    SELECT 
    ID,
    STCODE,
    DATE,
    ROW_NUMBER() OVER (ORDER BY DATE) AS rn,
    ROW_NUMBER() OVER (PARTITION BY STCODE ORDER BY DATE) AS str_rn
FROM 
    MyTable
)
 SELECT 
  ID,
  MIN(DATE) AS STDATE,
  MAX(DATE) AS ENDDATE
 FROM STS
  WHERE 
  STCODE in (3,8)
  GROUP BY ID
sql teradata row-number teradatasql
1个回答
0
投票

您需要确保这可以处理所有潜在的情况,但它适用于示例数据,并且是相当标准方法的要点。

基本原理 - 使用 Lead() 获取下一个状态代码和关联日期。然后过滤掉状态码处于非过期触发状态的记录。完成此操作后,您将只剩下每个状态序列中具有适当结束日期的第一条记录。

CREATE VOLATILE TABLE SampleData (
    ID INTEGER,
    STCODE INTEGER,
    event_date DATE
) ON COMMIT PRESERVE ROWS;

-- Inserts
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 3, DATE '2022-10-21');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 3, DATE '2022-10-22');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 3, DATE '2022-10-23');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 6, DATE '2022-10-25');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 3, DATE '2022-10-26');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (101, 7, DATE '2022-10-27');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (102, 8, DATE '2022-10-25');
INSERT INTO SampleData (ID, STCODE, event_date) VALUES (102, 5, DATE '2022-10-26');

with next_stcodes as (
select sd.*,
       lead(event_date) over ( partition by id order by event_date) as end_date,
       lead(stcode) over ( partition by id order by event_date) as next_stcode
  from SampleData sd)
select id,
       event_date,
       coalesce(end_date, DATE '9999-12-31') as end_date
  from next_stcodes
 where stcode in (3,8)
   and (
       next_stcode not in (3,8)
    or next_stcode is null
       );
© www.soinside.com 2019 - 2024. All rights reserved.