【问题标题】:Oracle query to fill in the missing data in the same tableoracle查询填补同一张表中缺失的数据
【发布时间】:2020-10-15 17:08:41
【问题描述】:

我在 oracle 中有一个表,其中缺少给定 id 的数据。我试图找出从开始日期填写数据的 sql:01/01/2019 到 end_dt:10/1/2020。请参阅下面的输入数据。对于状态键,可以根据其先前的状态键填充数据。见输入:

预期输出:

【问题讨论】:

  • 这并不难——但我想澄清一些事情。数据缺失时(2019 年初),为什么填充为-1?表示数据缺失的自然方式是null,而不是一些虚构的、否则无效的值。
  • 此外,我不知道您将如何推断新记录的日期 (MON)。请详细描述逻辑。
  • 值 -1 只是 null 的一个组成值。 Mon 列表示 2019 年 1 月 1 日和 2020 年 10 月 1 日之间每个月的第一天

标签: sql oracle datetime recursive-query analytic-functions


【解决方案1】:

您可以使用递归查询来生成日期,然后使用cross join 生成日期,并在表中使用不同的ids 列表。然后,使用窗口函数将缺失的键值带入:

with recursive cte (mon) as (
    select date '2019-01-01' mon from dual
    union all select add_months(mon, 1) from cte where mon < date '2020-10-01'
)
select i.id, 
    coalesce(
        t.status_key, 
        lead(t.previous_status_key ignore nulls) over(partition by id order by c.mon)
    ) as status_key,
    coalesce(
        t.status_key,
        lag(t.status_key ignore nulls, 1, -1) over(partition by id order by c.mon)
    ) previous_status_key,
    c.mon
from cte c
cross join (select distinct id from mytable) i
left join mytable t on t.mon = c.mon and t.id = i.id

您没有详细说明如何带回丢失的status_keys 和previous_status_keys。以下是查询的作用:

  • status_key取自下一个非nullprevious_status_key

  • previous_status_key取自最后一个非nullstatus_key,默认为-1

【讨论】:

    【解决方案2】:

    您可以生成日期,然后使用cross join 和一些额外的逻辑来获取您想要的信息:

    with dates (mon) as (
          select date '2019-01-01' as mon
          from dual
          union all
          select mon + interval '1' month
          from dates
          where mon < date '2021-01-01'
         )
    select d.mon, i.id,
           coalesce(t.status_key,
                    lag(t.status_key ignore nulls) over (partition by i.id  order by d.mon)
                   ) as status_key,
           coalesce(t.previous_status_key,
                    lag(t.previous_status_key ignore nulls) over (partition by i.id  order by d.mon)
                   ) as previous_status_key
    from dates d cross join
         (select distinct id from t) i left join 
         t
         on d.mon = t.mon and i.id = i.id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多