将一行的值分布在 Redshift 表中的多个列上?

Posted

技术标签:

【中文标题】将一行的值分布在 Redshift 表中的多个列上?【英文标题】:Spreading the values of a row over multiple columns in a Redshift table? 【发布时间】:2017-04-10 16:26:43 【问题描述】:

我有一个 Redshift 表,其中的示例行具有以下结构:

id                url
12345             http://www.things.com/details/?foo=hello&bar=world&baz=John+Smith
45678             http://www.things.com/details/?foo=hello&bar=america&booz=Howard+Jones&other_field=Portugal

我想提取 url 中 ? 之后的所有内容,对于每个 &,将 = 左侧的值添加到键列,将右侧的值添加到值列。在给定的 URL 中没有确定数量的 &。期望的输出如下:

id               key          value
12345            foo          hello
12345            bar          world
12345            baz          John+Smith
45678            foo          hello
45678            bar          america
45678            booz         Howard+Jones
45678            other_field  Portugal

我现在的解决方案是选择一个相当高的数字并编写一个 Python 脚本,该脚本编写相同的查询,每个整数都有一个新的UNION ALL。我在每次迭代期间使用SPLIT_PART(SPLIT_PART(SPLIT_PART(url, '?', 2), '&', i), '=', 1)SPLIT_PART(SPLIT_PART(SPLIT_PART(url, '?', 2), '&', i), '=', 2) 解析出所需的字段。

【问题讨论】:

Redshift有regexp_split_to_table()吗? No it does not. 【参考方案1】:

这是其他几个问题的重复:splitting rows in Redshift,Split values over multiple rows in RedShift。

我认为这在 Redshift 中并不容易,因为 AFAIK 没有将单行转换为多行的功能。

我提到的相关问题还提供了一些有用的技巧,可能会有所帮助。我认为最好的方法是加入一个序列号表(没有任何连接谓词)并将该数字用于SPLIT_PART,可能使用过滤器来消除不匹配的行。

其他一些系统也有这方面的功能,例如Postgres 有 regexp_split_to_arrayregexp_split_to_table,Snowflake 有 SPLIT + FLATTEN(免责声明 - 我在这个系统上工作)。

【讨论】:

以上是关于将一行的值分布在 Redshift 表中的多个列上?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 MYSQL 中的连接从多个表中获取多个列并在非空列上显示数据以及在空列上显示 null 或零

如何将 TIMESTAMP 转换为 VARCHAR 并将其保存到 Redshift 中的另一个表中?

如何防止在表中的多个下拉列表中选择相同的值并 POST 到服务器

是否需要根据表中的唯一值将列分解为多个列?

Redshift中的存储过程将数据加载到表中

您可以从 Redshift 中的 python UDF 返回多个值吗?