填写缺失的日期 Redshift

Posted

技术标签:

【中文标题】填写缺失的日期 Redshift【英文标题】:Filling in missing dates Redshift 【发布时间】:2020-12-28 15:36:20 【问题描述】:

我有一张如下所示的表格:

Account   Value   Last_Day_in_Month

ABC       7        2018-06-30
ABC      12        2018-06-30
ABC       3        2018-08-31
FGH      57        2019-01-31
FGH      13        2019-03-31
FGH       127      2019-03-31

对于每个帐户,我需要填写与每个月的最后一天对应的缺失日期,以便结果表仅填写上个月的值(您会注意到另外两行)

Account   Value   Last_Day_in_Month

ABC       7        2018-06-30
ABC      12        2018-06-30
ABC      12        2018-07-31
ABC       3        2018-08-31
FGH      57        2019-01-31
FGH      57        2019-02-28
FGH      13        2019-03-31
FGH       127      2019-03-31

我有许多帐户,每个帐户都有不同的开始和停止时间(Last_Day_in_Month),所以我只需要填写每个帐户的最小和最大月份之间的缺失月份。因为我可能有多个值对应于每个帐户的一个月结束日期,所以我当前的解决方案是使用带有添加一天的案例语句的潜在客户和仅包含每个月的最后一天的日期表并执行交叉加入。但是,我认为这很混乱,而且我确信有更好的方法我不知道。这是我目前的解决方案...

select
        *,
        lead(Last_Day_in_Month,1)over (
            partition by Account
            order by Last_Day_in_Month
        ) as intermed2,

        case 
            when intermed2 = Last_Day_in_Month
            then dateadd('day',1, intermed2)

            else intermed2

        end as next_last_day

    from table
    cross join dates 
        where dates.date_actual >= table.Last_Day_in_Month
            and dates.date_actual < table.next_last_day 

欢迎提出任何建议。

【问题讨论】:

【参考方案1】:

对于合理数量的行,您正在做的事情很好。为了清楚起见,我建议的一件事是从交叉连接更改为带有 ON 子句的右连接。查询计划者应该看穿你所拥有的并计划一个有效的查询,所以只是一个 nit。

还有许多其他方法可以做到这一点,您可以通过在堆栈溢出中搜索“间隙和孤岛”来找到示例。我得到的最大反馈是关于创建额外的行。您正在做的是为缺少的月份创建新行,这对于相当小的表来说很好,因为当您添加行时它们不会变得超级大。例如,如果您有一个包含 1000 亿行的表,并且您的平均间隙大小为 2,那么您将创建一个包含 3000 亿行的结果。制作这么多数据永远不会快速或高效。所以你说你有“许多帐户”,多少是多少?

如果数据量可以容纳在内存中,或者您只是偶尔执行一次此操作,那么创建行就可以了。如果这是作为正在进行的查询的一部分完成的,并且创建的数据会很大,那么我会重新考虑为什么需要创建数据来执行查询。一般来说,Redshift 存储非常大的数据集,并且将这些行乘以其他因素(日期)会导致查询速度非常慢。如果打算将此数据缩减为一些较小的结果,您将需要找到一种方法来创建此结果,而无需制作如此大的中间数据集。

【讨论】:

感谢您的反馈。就帐户数量而言……我们在成千上万的范围内进行操作,就时间序列而言,可能是 10M 或更少的行。您能否详细说明为什么带有 ON 子句的右连接会更好?我看到一个右连接引入了许多不适用于某些帐户的日期。我应该早点说,但是每个帐户都有一个订阅开始和结束日期,因此正确加入日期表是没有意义的,因为每个帐户最终都会保留日期表中的所有日期,即使是开始和结束日期之外的日期我绝对不想要。 如果间隔日期的数量平均少于 10 个,则使用 JOIN 方法可能可以使用 10M 行。创建大量数据可能会变得昂贵。你没喝够咖啡就抓住了我——我误读了 SQL,应该是 LEFT JOIN 和一个带有不等式条件的 ON 子句。这主要是一个可读性问题 - 您的查询所说的是将表中的每一行与日期中的每一行连接起来,然后删除不符合 WHERE 子句的行。查询优化器将意识到这实际上是一个 JOIN ON 并重写查询。正如我所说,这是一个傻瓜。

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

根据 max 和 min 填写缺失的日期 pandas

根据 max 和 min 填写缺失的日期 pandas

填写运行总计的缺失日期

ORACLE SQL:填写缺失的日期

SQL Server:填写每个实体具有不同日期范围的缺失日期

按日期和组聚合并在大查询中填写缺失的日期