从 Redshift 中的表中获取缺失的日期

Posted

技术标签:

【中文标题】从 Redshift 中的表中获取缺失的日期【英文标题】:Get missing dates from table in Redshift 【发布时间】:2016-09-29 10:02:48 【问题描述】:

我在 Redshift 中有一个表,其中包含一个日期列和一些其他数据:

+------------+-------+
|    Date    | Value |
+------------+-------+
| 2016-09-25 |     1 |
| 2016-09-28 |     2 |
| 2016-09-29 |     3 |
+------------+-------+

我想从此表中获取“缺失”的日期。因此,从上面的示例中,如果我想获取从 7 天前到现在的所有缺失日期,我想生成一个返回的查询:

2016-09-22
2016-09-23
2016-09-24
2016-09-26
2016-09-27

我尝试使用 generate_series(..) 函数来生成所有日期,然后将它们过滤掉以查找表中已经存在的日期。所以,类似:

    select CURRENT_DATE + i as MyDate
from generate_series(date '2016-09-22'- CURRENT_DATE, date '2016-09-29' - CURRENT_DATE ) i 
where MyDate not in (select [Date] from MyTable)

在这种情况下,我遇到错误“我的日期”不存在。我也尝试过使用 and EXCEPT 子句,然后产生错误:

INFO:  Function "generate_series(integer,integer)" not supported.

[Err] ERROR:  Specified types or functions (one per INFO message) not supported on Redshift tables.

我尝试过的各种其他事情都会产生该错误,我可以单独运行 generate_series(..) 但如果我尝试使用任何其他子句等,它就会失败。

这在 Redshift 中可以实现吗?

【问题讨论】:

【参考方案1】:

Redshift 不完全支持 generate_series,我发现您可以单独使用它,但是它生成的数据无法以任何方式与任何其他 redshift 功能结合。

您最好的选择是创建一个每天一行的 redshift 表,并在连接中使用该表,如下所示

select date from dates_table
where date not in (select date from my_table)

在表格中有可用于此日期列表的资源,此表格通常称为日期维度,并在星型数据仓库中使用。

例如 sisense date dimension

使用 excel 生成日期列表,然后保存为 CSV 可能同样容易

使用 redshift COPY 命令将日期加载到 redshift 表中。

【讨论】:

啊,好吧,我试图避免这种情况,但看起来没有太多选择。我也尝试将日期加载到临时表中,但正如你所说,如果你将它与任何东西结合起来——即使是插入,它也不起作用 我提供了一个可能感兴趣的答案:)【参考方案2】:

我设法找到了一种解决方法,它涉及另一种不使用 generate_series(..) 来生成一系列数字的方法。不确定它的性能如何,但这可能会有所帮助。感谢我在下面找到的博客链接。在他们的示例中,我认为他们建议将数字转储到表格中并使用它,但在下面我只是使用子查询来显示:

https://discourse.looker.com/t/generating-a-numbers-table-in-mysql-and-redshift/482

SELECT CURRENT_DATE - CAST ( days AS INT ) AS [Date]
FROM
 (SELECT 
    CAST (p0.n + p1.n*2 + p2.n * POWER(2,2) + p3.n * POWER(2,3)+ p4.n * POWER(2,4)+ p5.n * POWER(2,5) AS INT) AS days
      FROM 
        (SELECT 0 as n UNION SELECT 1) p0,
        (SELECT 0 as n UNION SELECT 1) p1,
        (SELECT 0 as n UNION SELECT 1) p2,
        (SELECT 0 as n UNION SELECT 1) p3,
        (SELECT 0 as n UNION SELECT 1) p4,
        (SELECT 0 as n UNION SELECT 1) p5
WHERE (p0.n + p1.n*2 + p2.n * POWER(2,2) + p3.n * POWER(2,3)+ p4.n * POWER(2,4)+ p5.n * POWER(2,5)) <= 7
)
EXCEPT
SELECT Date FROM MyTable

注意:在我的原始示例中,我只需要前 3 个值(选择中的 p3 最多)。这个例子将涵盖更多/更高的数字

【讨论】:

我需要返回 180 天,您的解决方案似乎不可能吧?

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

Redshift 查询每日生成的表

在 Redshift 中使用 python UDF 中的表

如何获取日期范围内的缺失值?

从sql中的表中减去两个日期

从 stl_load_commits 获取 Redshift COPY 命令的表名

Redshift - 问题在存储在表中的表中显示时差