在 Redshift 中的不同行上返回 JSON 数组列的元素

Posted

技术标签:

【中文标题】在 Redshift 中的不同行上返回 JSON 数组列的元素【英文标题】:Return elements of JSON array column on separate rows in Redshift 【发布时间】:2020-01-13 08:36:01 【问题描述】:

我有一个 Redshift 表,其中一列中有一个 JSON 数组:

 id | metadata
---------------------------------------------------------------------------
 1  | ["pet":"dog","country":"uk", "pet":"cat","country":"us"]
 2  | ["pet":"cat","country":"uk"]
 3  | []

我想要一个如下所示的表格:

 id |   pet   |  country
------------------------
 1  | dog       | uk
 1  | cat       | us
 2  | cat       | uk

有没有办法在 Redshift 表上使用 sql 命令和/或 python 用户定义函数来做到这一点

【问题讨论】:

【参考方案1】:

我将这种(丑陋的)方法用于 Redshift。让seq 成为一个包含单个字段num 的表,其中包含从 1 到 10000 的数字(假设一行中的宠物不超过 10000 只)。您可以使用generate_series(1, 10000),但由于奇怪的原因它会变慢:(

select
  id,
  JSON_EXTRACT_PATH_TEXT(single_metadata, 'pet') as pet,
  JSON_EXTRACT_PATH_TEXT(single_metadata, 'country') as country
from
(
  select
    t.id,
    cast(JSON_EXTRACT_ARRAY_ELEMENT_TEXT(t.metadata, num) as json) as single_metadata
  from 
    t join seq -- or (select num from generate_series(1, 10000))
  on num <= json_array_length(t.metadata)
)

【讨论】:

我试过这个,但我不想硬编码数字,比如这里到 10000 你可以通过select max(json_array_length(t.metadata)) from t这样的查询得到这个号码 所以我有一个表 seq CREATE TEMP TABLE seq (i int); INSERT INTO seq VALUES(0),(1),(2); 但我如何使用 select max(json_array_length(t.metadata)) 作为插入选择组合命令在 seq 中插入数据? 只能通过python脚本:(

以上是关于在 Redshift 中的不同行上返回 JSON 数组列的元素的主要内容,如果未能解决你的问题,请参考以下文章

SQL计算GBQ中表中的不同行数

在自动调整大小的标签中的不同行上显示 Swift 字符串数组

ListView 中的不同行布局

如何从一列的不同行中获取值以分隔列

MSVC 和 g++ 中的不同行尾

识别 2 个表中的不同行