【问题标题】:Get missing dates from table in Redshift从 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 中可以实现吗?

【问题讨论】:

    标签: sql database postgresql amazon-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 天,您的解决方案似乎不可能吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多