如何在 Oracle 中按组填写缺失的日期

Posted

技术标签:

【中文标题】如何在 Oracle 中按组填写缺失的日期【英文标题】:How do I fill in missing dates by group in Oracle 【发布时间】:2020-11-10 02:47:39 【问题描述】:

我在 Oracle SQL 中有下表:

+------------+-------+
| COLOR_DATE | COLOR |
+------------+-------+
| 28-Jan-20  | red   |
| 3-Feb-20   | red   |
| 6-Feb-20   | red   |
| 16-Apr-20  | blue  |
| 19-Apr-20  | blue  |
| 23-Apr-20  | blue  |
| 2-May-20   | blue  |
+------------+-------+

我想根据COLOR 填写缺失的日期。也就是说,我想获取每个COLOR 的最小日期和最大日期,并生成填充了缺失日期的行。结果表如下所示:

+------------+-------+
| COLOR_DATE | COLOR |
+------------+-------+
| 28-Jan-20  | red   |
| 29-Jan-20  | red   |
| 30-Jan-20  | red   |
| 31-Jan-20  | red   |
| 1-Feb-20   | red   |
| 2-Feb-20   | red   |
| 3-Feb-20   | red   |
| 4-Feb-20   | red   |
| 5-Feb-20   | red   |
| 6-Feb-20   | red   |
| 16-Apr-20  | blue  |
| 17-Apr-20  | blue  |
| 18-Apr-20  | blue  |
| 19-Apr-20  | blue  |
| 20-Apr-20  | blue  |
| 21-Apr-20  | blue  |
| 22-Apr-20  | blue  |
| 23-Apr-20  | blue  |
| 24-Apr-20  | blue  |
| 25-Apr-20  | blue  |
| 26-Apr-20  | blue  |
| 27-Apr-20  | blue  |
| 28-Apr-20  | blue  |
| 29-Apr-20  | blue  |
| 30-Apr-20  | blue  |
| 1-May-20   | blue  |
| 2-May-20   | blue  |
+------------+-------+

请注意COLORs 的数量不定。

谁能告诉我如何在 Oracle SQL 中做到这一点?

任何帮助将不胜感激!

为方便起见,下面是在Oracle中生成表的sql查询:

with a as (
            select to_date('1/28/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'red' as color   
                   from dual
            union
            select to_date('2/3/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'red' as color  
                   from dual
            union
            select to_date('2/6/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'red' as color  
                   from dual
            union
            select to_date('4/16/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'blue' as color   
                   from dual
            union
            select to_date('4/19/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'blue' as color  
                   from dual
            union
            select to_date('4/23/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'blue' as color  
                   from dual
            union
            select to_date('5/2/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date
                   ,  'blue' as color  
                   from dual
                )
select *
from a

【问题讨论】:

【参考方案1】:

您可以使用Recursive Subquery Factoring 来生成间隔:

with tbl as (
    select to_date('1/28/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date, 'red' as color  from dual union
    select to_date('2/3/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date,  'red' as color  from dual union
    select to_date('2/6/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date,  'red' as color  from dual union
    select to_date('4/16/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date, 'blue' as color from dual union
    select to_date('4/19/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date, 'blue' as color from dual union
    select to_date('4/23/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date, 'blue' as color from dual union
    select to_date('5/2/2020 11:51', 'MM/DD/YYYY HH24:MI') as color_date,  'blue' as color from dual
),
tbl_min_max as (
    select t.color, min(trunc(color_date)) begin_interval, max(trunc(color_date)) end_interval from tbl t group by t.color
),
tbl_interval(color, begin_interval, end_interval, color_date) as (
    select color, begin_interval, end_interval, begin_interval from tbl_min_max
    union all 
    select color, begin_interval, end_interval, color_date + 1 from tbl_interval where color_date < end_interval 
)
select 
    t.color, t.color_date
from 
    tbl_interval t
order by
    t.color, t.color_date

【讨论】:

以上是关于如何在 Oracle 中按组填写缺失的日期的主要内容,如果未能解决你的问题,请参考以下文章

在Oracle中按组不使用聚合函数或行到列

如何在 google BigQuery 中填写缺失的日期

在Impala中按组减去最大,最小日期

ORACLE SQL:填写缺失的日期

如何在 R 的列表中按组获取平均值

如何在mysql中按组查找累积值?