【问题标题】:Find the first instance of a null value in a group as long as no non null comes after - Teradata SQL只要后面没有非空值,就可以在组中查找空值的第一个实例 - Teradata SQL
【发布时间】:2016-01-05 18:40:31
【问题描述】:

我试图找到某个字段为空的第一行,但需要注意的是后面不能有非空。如果没有空值或非空值出现在空值之后,那么我根本不想返回那个值。我正在使用 Teradata SQL,下面的模拟数据集应该可以说明我在寻找什么。

ID | Date      | Field_Of_Interest
A  | 1/1/2015  | 1
A  | 2/1/2015  | 1
A  | 3/1/2015  | 
A  | 4/1/2015  | 
A  | 5/1/2015  | 
B  | 1/1/2015  | 1
B  | 2/1/2015  | 1
B  | 3/1/2015  | 
B  | 4/1/2015  | 1
B  | 5/1/2015  | 
C  | 1/1/2015  | 1
C  | 2/1/2015  | 1
C  | 3/1/2015  | 1
C  | 4/1/2015  | 1
C  | 5/1/2015  | 1
D  | 1/1/2015  | 1
D  | 2/1/2015  | 1
D  | 3/1/2015  | 
D  | 4/1/2015  | 
D  | 5/1/2015  | 1

期望的结果:

ID | Date      
A  | 3/1/2015
B  | 5/1/2015

由于 C 和 D 的最后一条记录为非空值,所以我不希望它们全部。

在 B 或 D 之类的情况下,我不能只取 Field_Of_Interest 为空的日期字段的最小值。我的另一个想法是找到 null 的最小值和非 null 的最大值,如果最小值的日期大于最大值的日期,请使用它。问题在于 B 中的非空值出现在空值之后,然后又返回空值。

有什么想法吗?

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    这能满足你的需求吗?

    SELECT
        T1.ID,
        MIN(T1.some_date) AS some_date
    FROM
        My_Table T1
    WHERE
        T1.some_column IS NULL AND
        NOT EXISTS (SELECT * FROM My_Table T2 WHERE T2.ID = T1.ID AND T2.some_date > T1.some_date AND T2.some_column IS NOT NULL)
    GROUP BY
        T1.ID
    

    或者:

    SELECT
        T1.id,
        MIN(T1.some_date) AS some_date
    FROM
        My_Table T1
    LEFT OUTER JOIN My_Table T2 ON
        T2.id = T1.id AND
        T2.some_date > T1.some_date AND
        T2.some_column IS NOT NULL
    WHERE
        T1.some_column IS NULL AND
        T2.id IS NULL
    GROUP BY
        T1.id
    

    【讨论】:

    • 谢谢!我使用了第一个,效果很好,我不知道 NOT EXISTS,这对我来说是一个新的,非常有帮助。再次感谢您的帮助,这太棒了。
    【解决方案2】:

    您可以使用不同的行号或使用子查询来执行此操作。后一种方法会产生如下查询:

    select id, min(date)
    from t
    where t.field_of_interest is null and
          not exists (select 1
                      from t
                      where t2.id = t.id and t2.date > t.date and
                            t2.field_of_interest is not null
                     )
    group by id;
    

    【讨论】:

    • 感谢您的帮助,我已经将上面的答案标记为正确(它具有相同的逻辑,你们肯定在同一时间回答了)但我至少给了你一个赞成票。再次感谢,这是一个非常棒的解决方案。
    【解决方案3】:

    您可以使用窗口聚合函数通过单个表访问获得预期结果。根据实际数据/查询,这可能会更有效。

    SELECT ID, MIN(dt)
    FROM
     (
       SELECT *
       FROM tab
       QUALIFY
          -- returns NULL until the first row with a value in Field_Of_Interest
          MIN(Field_Of_Interest) 
          OVER (PARTITION BY ID
                ORDER BY dt DESC
                ROWS UNBOUNDED PRECEDING) IS NULL
     ) AS dt
    GROUP BY 1
    

    【讨论】:

      猜你喜欢
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 2018-05-20
      • 2016-04-26
      相关资源
      最近更新 更多