【问题标题】:Nested Case when SQL TeradataSQL Teradata 时的嵌套案例
【发布时间】:2021-05-04 19:40:22
【问题描述】:

请我有以下数据,我需要计算每个 ID 的 Current_date 和 Max Date 之间的日期差异,仅限 Active Status,日期差异的结果将位于最大日期旁边,并且其他记录返回 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     |

【问题讨论】:

  • 也许是愚蠢的问题,但为什么不将两者与 AND => CASE WHEN STATUS = 'Active' AND Date = MAX(Date) OVER (PARTITION BY ID) THEN CURRENT_DATE - MAX(Date) OVER ( PARTITION BY ID) ELSE NULL END AS Duration
  • @hhoeck 我尝试使用 AND 但它也会在每个日期重复结果
  • 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 Status ORDER BY DATE DESC) AS RNUM FROM CTE) CTE2 ORDER BY ID, DATE
  • 除非您每个 id/date 有多个行,否则 hhoeck 的建议应该按预期工作。

标签: sql nested teradata


【解决方案1】:

如果您只想在带有“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() 的不必要的第二次调用。

【讨论】:

    【解决方案2】:
    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;
    

    【讨论】:

      猜你喜欢
      • 2017-03-09
      • 2014-06-25
      • 2020-05-15
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多