如何从Amazon Redshift中的范围生成日期列表?

Sco*_*den 1 amazon-redshift

在PostgreSQL中获取日期范围显示了如何在PostgreSQL中获取日期范围。但是,Redshift不支持generate_series()

ans=> select (generate_series('2012-06-29', '2012-07-03', '1 day'::interval))::date;
ERROR:  function generate_series("unknown", "unknown", interval) does not exist
HINT:  No function matches the given name and argument types. You may need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)

有没有办法复制generate_series()Redshift中的内容?

Hal*_*Ali 7

hack,但可以:

使用具有许多行的表和窗口函数来生成序列

只要生成的序列小于用于生成序列的表中的行数,此方法就可以使用

WITH x(dt) AS (SELECT '2016-01-01'::date)
SELECT 
    dateadd(
        day, 
        COUNT(*) over(rows between unbounded preceding and current row) - 1, 
    dt)
FROM users, x 
LIMIT 100
Run Code Online (Sandbox Code Playgroud)

初始日期2016-01-01控制开始日期,限制日期控制生成的系列中的天数。

更新:

Redshift 对该功能提供了部分支持,generate_series但不幸的是在其文档中未提及该功能。

起作用,并且是截至该日期(2018-01-29)生成一系列日期的最短,最清晰的方法:

SELECT ('2016-01-01'::date + x)::date 
FROM generate_series(1, 100, 1) x
Run Code Online (Sandbox Code Playgroud)

  • `generate_series` 在领导节点上运行时将起作用。但是,当将该查询与实际表连接时,它将尝试在其他节点上执行并失败。来自 Redshift [有关不支持的 PostgreSQL 功能的文档](https://docs.aws.amazon.com/redshift/latest/dg/c_unsupported-postgresql-functions.html):_“某些不支持的函数在运行时不会返回错误领导节点"_ (2认同)

mic*_*mus 5

如果您不想依赖任何现有表格,一个选择是预先生成一个填充一系列数字的系列表格,每行一个。

create table numbers as (
  select
          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)
          + p6.n * power(2,6)
          + p7.n * power(2,7)
          + p8.n * power(2,8)
          + p9.n * power(2,9)
          + p10.n * power(2,10)
          as number
        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,
          (select 0 as n union select 1) p6,
          (select 0 as n union select 1) p7,
          (select 0 as n union select 1) p8,
          (select 0 as n union select 1) p9,
          (select 0 as n union select 1) p10
  order by 1
);
Run Code Online (Sandbox Code Playgroud)

这将创建一个数字从 0 到 2^10 的表,如果您需要更多数字,只需添加更多子句:D

一旦你有了这张桌子,你就可以加入它来代替 generate_series

with date_range as (select 
   '2012-06-29'::timestamp as start_date , 
   '2012-07-03'::timestamp as end_date
)
select
    dateadd(day, number::int, start_date)
from date_range
inner join numbers on number <= datediff(day, start_date, end_date)
Run Code Online (Sandbox Code Playgroud)