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

时间:2018-01-24 17:54:17

标签: amazon-redshift

Getting date list in a range in 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.

有没有办法复制generate_series()在Redshift中的作用?

3 个答案:

答案 0 :(得分:6)

一个黑客,但有效:

使用包含许多行的表,以及用于生成系列

的窗口函数 只要您生成的系列小于您用于生成系列的表格中的行数

就可以正常工作

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

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

<强>更新

Redshift对generate_series函数具有部分支持,但遗憾的是在文档中没有提到它。

这个工作,是最短的&amp;截至此日期(2018-01-29)生成一系列日期的最清晰的方式:

SELECT ('2016-01-01'::date + x)::date 
FROM generate_series(1, 100, 1) x

答案 1 :(得分:2)

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

unlines (concat <$> permutations listofstrings)

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

获得此表后,您可以加入该表作为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 );

的替代
generate_series

答案 2 :(得分:1)

@michael_erasmus 这很有趣,为了更好的性能,我做了一些改变。

CREATE OR REPLACE VIEW v_series_0_to_1024 AS SELECT
  p0.n 
  | (p1.n << 1) 
  | (p2.n << 2) 
  | (p3.n << 3) 
  | (p4.n << 4) 
  | (p5.n << 5) 
  | (p6.n << 6) 
  | (p7.n << 7) 
  | (p8.n << 8) 
  | (p9.n << 9)
  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
order by number

过去 30 天的日期系列:

select dateadd(day, -number, current_date) as dt from v_series_0_to_1024 where number < 30