在Redshift中generate_series()方法失败

DJo*_*DJo 6 generate-series amazon-redshift

当我运行SQL查询时:

 select generate_series(0,g)
 from ( select date(date1) - date(date2) as g from mytable ;
Run Code Online (Sandbox Code Playgroud)

它返回一个错误:

 INFO:  Function "generate_series(integer,integer)" not supported.
 ERROR:  Specified types or functions (one per INFO message) not supported 
 on Redshift tables.
Run Code Online (Sandbox Code Playgroud)

但是当我运行这个查询时:

select  generate_series(0, g) from (select 5 as g)
Run Code Online (Sandbox Code Playgroud)

它返回以下响应:

 generate_series
-----------------
 0
 1
 2
 3
 4
 5
(6 rows)
Run Code Online (Sandbox Code Playgroud)

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

DJo*_*DJo 14

generate_series()Redshift不完全支持该功能.请参阅开发人员指南的不支持的PostgreSQL函数部分:

在特定示例中,第二查询完全在领导节点上执行,因为它不需要扫描任何实际表数据,而第一查询试图选择数据并且因此将在计算节点上执行.

更新:

generate_series现在正在使用Redshift.

SELECT CURRENT_DATE::TIMESTAMP  - (i * interval '1 day') as date_datetime 
FROM generate_series(1,31) i 
ORDER BY 1
Run Code Online (Sandbox Code Playgroud)

这将生成过去30天的日期

  • 到了 2023 年,“generate_series”仍然仅在主节点上受支持,但在计算节点上不受支持。 (4认同)
  • 这并不能解决计算节点不支持 generate_series 的问题。如果你尝试将这个 select 加入一个表或在 CTE 中使用它,或者创建一个临时表,同样会发生同样的 ERROR。 (3认同)

sys*_*ack 6

您可以使用窗口函数来实现类似的结果.这需要一个现有的表(如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
Run Code Online (Sandbox Code Playgroud)

您可以使用此方法获取其他时间范围以及存储目的.此版本生成前一天的所有分钟,因此您可以对其进行左连接并获取数据.

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
Run Code Online (Sandbox Code Playgroud)

我可能在这里第一次见到这个.