Amazon redshift generate_series()方法在红移中失败

Amazon redshift generate_series()方法在红移中失败,amazon-redshift,generate-series,Amazon Redshift,Generate Series,运行SQL查询时: select generate_series(0,g) from ( select date(date1) - date(date2) as g from mytable ; 它返回一个错误: INFO: Function "generate_series(integer,integer)" not supported. ERROR: Specified types or functions (one per INFO message) not supporte

运行SQL查询时:

 select generate_series(0,g)
 from ( select date(date1) - date(date2) as g from mytable ;
它返回一个错误:

 INFO:  Function "generate_series(integer,integer)" not supported.
 ERROR:  Specified types or functions (one per INFO message) not supported 
 on Redshift tables.
但当我运行此查询时:

select  generate_series(0, g) from (select 5 as g)
它返回以下响应:

 generate_series
-----------------
 0
 1
 2
 3
 4
 5
(6 rows)

为什么第二个查询有效,而第一个查询失败?

您没有使用PostgreSQL。您正在使用亚马逊红移

与红移表一起使用时,Amazon红移不支持
generate_series
。它在错误消息中就说了

要么使用真正的PostgreSQL,要么如果需要Redshift的功能,还必须在Redshift的限制范围内工作

您的第二个示例之所以有效,是因为它不使用任何红移表。

这在这里有效(第9.3.3页)。也许您的问题只是红移的结果——“功能”

红移不完全支持
generate_series()
函数。请参阅《开发人员指南》的一节:

在特定示例中,第二个查询完全在leader节点上执行,因为它不需要扫描任何实际的表数据,而第一个查询尝试选择数据,因此将在compute节点上执行

更新:

generate_series正在使用红移

SELECT CURRENT_DATE::TIMESTAMP  - (i * interval '1 day') as date_datetime 
FROM generate_series(1,31) i 
ORDER BY 1
这将生成过去30天的日期

您可以使用来获得类似的结果。这需要一个现有的表(如
stv_blocklist
)进行种子筛选,该表至少具有所需的行数,但不会太多,这可能会降低速度

with days as (
    select (dateadd(day, -row_number() over (order by true), sysdate::date)) as day 
    from [other_existing_table] limit 30
)
select day from days order by 1 asc
您也可以使用此方法获取其他时间范围,以达到扣合目的。此版本生成前一天的所有分钟数,以便您可以对其执行左连接并存储数据

with buckets AS (
    select (dateadd(minute, -row_number() over (order by true), sysdate::date)) as minute 
    from [other_table] limit 1440
)
select minute from buckets order by 1 asc

我可能是第一次看到这一点。

上面解释了它不起作用的原因。尽管如此,“我们能对此做些什么?”这一问题仍然悬而未决

如果您在任何平台上开发BI系统(无论是否支持生成器),使用带有数字和日期序列的维度表是非常方便的。如何在红移中创建一个

  • 在Postgres中,使用生成器生成必要的序列
  • 导出到CSV
  • 在红移中创建具有相同架构的表
  • 将CSV从步骤2导入到红移
  • 假设您创建了一个非常简单的表,名为
    calendar

     id, date
     1, 2017-01-01
     2, 2017-01-02
     ..., ...
     xxx, 2020-01-01
    
    因此,您的查询将如下所示:

    SELECT t.id, t.date_1, t.date_2, c.id as date_id, c.date
    FROM mytable t
    JOIN calendar c
    ON c.date BETWEEN t.date_1::date AND t.date_2::date
    ORDER BY 1,4
    

    在日历表中,您还可以有周、月、季度、工作日(周一、周二等)的第一个日期,这使得此类表对于基于时间的聚合非常有效。

    您是正确的,这不适用于红移。 看

    你可以用这样的东西

    with ten_numbers as (select 1 as num union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0)
    ,generted_numbers AS
    (
        SELECT (1000*t1.num) + (100*t2.num) + (10*t3.num) + t4.num-5000 as gen_num
        FROM ten_numbers AS t1
          JOIN ten_numbers AS t2 ON 1 = 1
          JOIN ten_numbers AS t3 ON 1 = 1
          JOIN ten_numbers AS t4 ON 1 = 1
    )
    select  gen_num from generted_numbers
    where gen_num between -10 and 0
    order by 1;
    

    您将需要使用leader节点支持的功能。诀窍是使用
    任何所需的表中的
    行数()。
    假设我们要生成一个从10天前到现在的日期序列:

       SELECT DATEADD('day', -n, (CURRENT_DATE+1)) AS generated_date
       FROM (SELECT ROW_NUMBER() OVER () AS n FROM my_table LIMIT 10) n
       ORDER BY generated_date DESC
    
    我们得到:

    generated_date
    2020-06-24 00:00:00
    2020-06-23 00:00:00
    2020-06-22 00:00:00
    2020-06-21 00:00:00
    2020-06-20 00:00:00
    2020-06-19 00:00:00
    2020-06-18 00:00:00
    2020-06-17 00:00:00
    2020-06-16 00:00:00
    2020-06-15 00:00:00
    

    显然,第一个子查询返回的是
    间隔
    而不是
    整数
    (因为:“generate_series(integer,interval)不存在”)请在错误消息中查看我的编辑。您没有使用PostgreSQL。您正在使用Amazon Redshift。因为您报告这是与Redshift一起使用的,并且Redshift没有版本控制,因此任何人都不能使用旧版本。我不明白为什么这个问题应该保持开放。我投票决定关闭。这不是一个只支持leader节点的函数吗?@Naveen现在可能是,但不是在我编写此.OP询问红移时。这并不能解决计算节点不支持generate_系列的问题。如果尝试将此select连接到表或在CTE中使用它,或创建临时表,则会发生相同的错误。
    generated_date
    2020-06-24 00:00:00
    2020-06-23 00:00:00
    2020-06-22 00:00:00
    2020-06-21 00:00:00
    2020-06-20 00:00:00
    2020-06-19 00:00:00
    2020-06-18 00:00:00
    2020-06-17 00:00:00
    2020-06-16 00:00:00
    2020-06-15 00:00:00