REDSHIFT:如何生成一系列数字而不在 redshift (Postgres 8.0.2) 中创建名为“数字”的表?

Posted

技术标签:

【中文标题】REDSHIFT:如何生成一系列数字而不在 redshift (Postgres 8.0.2) 中创建名为“数字”的表?【英文标题】:REDSHIFT: How can I generate a series of numbers without creating a table called "numbers" in redshift (Postgres 8.0.2)? 【发布时间】:2016-12-04 16:00:04 【问题描述】:

我需要为报表创建一个空的时间表系列,以便我可以将多个表中的连接活动留给它。一天中的每个小时都不一定有数据,但我希望它显示空或零以表示不活动,而不是省略一天中的那个小时。

在更高版本的 Postgres(8.0.2 之后)中,这在几个方面很容易:

SELECT unnest(array[0,1,2,3,4...]) as numbers

CROSS JOIN (select generate_series as hours from generate_series(now()::timestamp, now()::timestamp + interval '1 day', '1 hour'::interval )) date_series

Redshift 可以运行其中一些命令,但当您尝试将其与任何表一起运行时会引发错误。

我需要什么:

一种可靠的方式来生成一系列数字(例如 0-23)作为子查询,它将在 redshift 上运行(使用 postgres 8.0.2)。

【问题讨论】:

***.com/a/34167753/3019685 因为 Redshift 没有版本化,因此任何人都无法使用旧版本我不明白为什么这个问题应该保持开放。我投票关闭。 Redshift 现在支持这一点。 Evan Carroll,Redshift 不支持使用生成系列交叉连接到子查询中。它显示错误“Redshift 表不支持指定的类型或函数(每个 INFO 消息一个)。;” @EvanCarroll 是否在某处记录了对此的支持?我仍然看到在 redshift 文档中将 generate_series 列为“不支持”。我们迁移到 bigquery,所以我无法自己测试。 这能回答你的问题吗? sequence number generation function in AWS redshift 【参考方案1】:

很遗憾,Amazon Redshift 不允许将 generate_series() 用于表函数。解决方法似乎是创建一个数字表。

另见:

Using sql function generate_series() in redshift Generate Series in Redshift and mysql,看起来不太对,但确实引入了一些有趣的想法

【讨论】:

创建一个数字表让我非常讨厌。感觉就像在 python 脚本中一个一个地写出数字。这是错误的。 您可以创建一个date 表,其中包含DayOfWeekPublicHolidayMonthQuarter 等列。这是从日期中提取有用信息的常见做法.然后,您可以将此表重新用作Numbers 表而不会感到厌烦。【参考方案2】:

只要您的表格的行数多于所需系列的数字,这就是过去对我有用的方法:

select
    (row_number() over (order by 1)) - 1 as hour
from
    large_table
limit 24
;

返回数字0-23

【讨论】:

这是一个不错的解决方案,如果我使用 pg_catalog.pg_operator 之类的东西,我不必担心架构更改会破坏查询。 丑陋但有效 并再次交叉加入以获得更多值(pg_operator只有647个对象)。【参考方案3】:

我不喜欢仅仅为了获取行号列表而查询系统表。如果它像一天中的几个小时一样恒定且足够小,我会选择普通的旧UNION ALL

WITH 
  hours_in_day AS (
    SELECT 0 AS hour
    UNION ALL SELECT 1
    UNION ALL SELECT 2
    UNION ALL SELECT 3
    UNION ALL SELECT 4
    ...
    UNION ALL SELECT 23
  )

然后加入hours_in_day 到任何你想加入的地方。

【讨论】:

实际上,我在查询一个非常小的表并选择 row_number() 而不是 () 时运气更好。 Redshift 不能很好地处理重复的 UNION ALL 子查询,即使是一天中的几个小时,我们也看到 row_number 的性能更好。 This answer 还描述了如何使用CROSS JOINs 来调整它以生成更多的数字。【参考方案4】:

Recursion was released for Redshift in April 2021. 现在递归在 Redshift 中是可能的。您可以使用以下代码生成一系列数字(甚至表格)

with recursive numbers(NUMBER) as
(
select 1 UNION ALL
select NUMBER + 1 from numbers where NUMBER < 28
)

【讨论】:

以上是关于REDSHIFT:如何生成一系列数字而不在 redshift (Postgres 8.0.2) 中创建名为“数字”的表?的主要内容,如果未能解决你的问题,请参考以下文章

为 AWS Data Pipeline SqlActivity 指定 Redshift 架构,而不在 sql 脚本的开头添加“set search_path to ...”

如何在 Kafka 中进行转换(PostgreSQL-> Red shift )

Redshift 创建列表并用它搜索不同的表

Redshift 在多个条件下加入,但仅在一个条件不匹配时返回

redshift unload : 仅在字符字段中加上引号而不是数字

Kafka Connect 接收到不在公共模式中的 Redshift 表