【问题标题】:Teradata SQL: Search for the first time a value changes in a columnTeradata SQL:搜索列中值的第一次更改
【发布时间】:2018-02-09 00:10:10
【问题描述】:

因此,我有一个表格,可以每天跟踪客户帐户并记录每个工作日的值,例如该帐户的余额。

例如:

Acct_Nbr   Acct_Open_Date   System_Date   Balance
-------------------------------------------------
111        2017-12-01       2017-12-01    0.00
111        2017-12-01       2017-12-04    0.00
111        2017-12-01       2017-12-05    0.00
111        2017-12-01       2017-12-06    500.00
222        2017-12-01       2017-12-01    0.00
222        2017-12-01       2017-12-04    0.00
222        2017-12-01       2017-12-05    0.00
222        2017-12-01       2017-12-06    0.00
222        2017-12-01       2017-12-07    0.00
222        2017-12-01       2017-12-08    250.00

我正在尝试编写一个查询,该查询将返回 Acct_Open_Date 和余额首次变为 > 0 的 System_Date 之间的天数(即帐户获得资金的日期)。

我计划使用 case when 语句(即

根据上表,它会返回:

Time_to_fund   Count_of_accts
-----------------------------
<=5 days       1
6-10 days      1
>10 days       0

我不完全确定如何编写一个查询,该查询将基于每个帐户搜索每一行,直到找到 Balance > 0 的值,然后获取该行的 System_Date 并从中减去 Acct_Open_Date 到给我 # 天。

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: sql teradata gaps-and-islands


    【解决方案1】:
    select
       CASE WHEN diff <=  5 THEN'<=5 days'
            when diff <= 10 then '6-10 days'
            ELSE '>10 days'
       END as Time_to_fund,
       COUNT(*)
    from
     (
        select
           System_Date - Acct_Open_Date as diff -- number of days between
        from mytable
        where Balance > 0 
        qualify -- find the first row with a Balance > 5
           row_number()
           over (partition by Acct_Nbr
                 order by System_Date) = 1
     ) as dt
    

    【讨论】:

    • 我知道这将是一个带有窗口功能的东西,只是仍然无法完全理解它们是如何工作的。但是,如果我理解正确,您的查询所做的是它排除了 system_dates = 0 的所有行,找到第一行(由于 row_number() 函数,这将是 1,对吗?)并按 Acct_Nbr 对其进行分组,然后按顺序排序system_date 以便第一行是帐户获得资金的第一个日期。我理解正确吗?
    • @starfly 没错。 1:删除所有 0 行,2:对于每个 Acct_Nbr,按 System_Date 对所有行进行排序并仅返回第一(=最旧)行。如果 Acct_Open_Date 不包括在内,它会有点复杂:-)
    【解决方案2】:

    尝试在 GROUP BY 中使用 GROUP BY:

    SELECT CASE WHEN fund_times.Time_to_fund_in_days<= 5 THEN'<=5 days'
    when fund_times.Time_to_fund_in_days<= 10 then '6-10 days'
    ELSE '>10 days' END as Time_to_fund, COUNT(fund_times.acct_Number) AS Count_of_accts
        (SELECT t.acct_Number, MIN( (t.System_Date - t.Acct_Open_Date) * 86400) as Time_to_fund_in_days
        from table as T
        WHERE t.Balance>0
        GROUP BY t.acct_Number) AS fund_times
    GROUP BY CASE WHEN fund_times.Time_to_fund_in_days<= 5 THEN'<=5 days'
    when fund_times.Time_to_fund_in_days<= 10 then '6-10 days'
    ELSE '>10 days' END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2010-12-11
      • 2022-09-20
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多