SQL Teradata 时的嵌套大小写

Nested Case when SQL Teradata

请提供以下数据,我需要计算 Current_date 和每个 ID 的最大日期之间的日期差异(仅限 Active 状态),日期差异的结果将是位于最大日期和其他记录旁边一次 return NULL.

|ID  |Date  |Status   |
|----+------|---------|
|A   |1-Apr |Active   |
|A   |15-Apr|Active   |
|B   |1-Mar |Suspended|
|B   |15-Mar|Deactive |
|C   |1-Jan |Active   |
|C   |15-Jan|Active   |

我尝试使用以下查询,但每个日期都会重复结果

SELECT
    ID,
    Date, 
    CASE WHEN STATUS = 'Active' THEN
    CASE WHEN Date = MAX(Date) OVER (PARTITION BY ID)
         THEN CURRENT_DATE - MAX(Date) OVER (PARTITION BY ID) ELSE NULL END
ELSE NULL END AS Duration
FROM cte
ORDER BY ID, Date;

但我需要结果像下面这样

|ID  |Date  |Status   |Duration|
|----+------|---------|--------|
|A   |1-Apr |Active   |NULL    |
|A   |15-Apr|Active   |19      |
|B   |1-Mar |Suspended|NULL    |
|B   |15-Mar|Deactive |NULL    |
|C   |1-Jan |Active   |NULL    |
|C   |15-Jan|Active   |109     |

如果您只想在最近一行显示“ACTIVE”,则添加 row_number():

SELECT ID, Date, 
       (CASE WHEN STATUS = 'Active' AND
                  ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DATE DESC) = 1
             THEN CURRENT_DATE - Date
        END) as Duration
FROM cte
ORDER BY ID, Date;

请注意,您的代码看起来应该可以正常工作,除非 id 有重复的最近日期。然而,这个版本有点简单,避免了嵌套的 CASE 表达式和不必要的第二次调用 MAX().

SELECT ID,
       DATE,
       Status,
       CASE
         WHEN STATUS = 'Active' AND RNUM = 1 THEN CURRENT_DATE - DATE
         ELSE NULL
       END AS Duration
FROM (SELECT ID,
             DATE,
             Status,
             ROW_NUMBER() OVER (PARTITION BY ID,Status ORDER BY DATE DESC) AS RNUM
      FROM CTE) CTE2
ORDER BY ID,
         DATE;