填写缺失的日期 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,应该是以上是关于填写缺失的日期 Redshift的主要内容,如果未能解决你的问题,请参考以下文章