问题描述
这是该列中的示例数据。我想动态提取仅与5相关联的值。
'{"2113":5,"2112":5,"2114":4,"2511":5}'
最终结构应为3行名称和值?
我想要的最终结果,
value | Key
2113 5
2112 5
2115 5
解决方法
因此,您需要做的是取消json对象的嵌套(每行有一个键-值对)。在Readshift中取消嵌套非常棘手。需要一个序列表,然后使用适当的过滤条件填充CROSS JOIN
。通常,取消嵌套是在数组上完成的,这样会更容易,因为索引很容易生成。要取消嵌套键值映射(JSON对象),需要知道所有键(Redshift无法做到)。您的示例很幸运,因为键是整数,并且基数相对较低。
这是一个草图解决方案。请注意,您将必须更改创建序列表的方式:
WITH input(json) AS (
SELECT '{"2113":5,"2112":5,"2114":4,"2511":5}'::varchar
),sequence(idx) AS (
-- instead of the below you should use sequence table
SELECT 2113
UNION ALL
SELECT 2112
UNION ALL
SELECT 2114
UNION ALL
SELECT 2511
UNION ALL
SELECT 2512
UNION ALL
SELECT 2513
UNION ALL
SELECT 2514
),unnested(key,val) AS (
SELECT idx::varchar as key,json_extract_path_text(json,key) as val
FROM input
CROSS JOIN sequence
WHERE val IS NOT NULL
)
SELECT *
FROM unnested
WHERE val = 5
key | val
2113 | 5
2112 | 5
2511 | 5
如何在Redshift中生成大序列:
...
sequence(idx) AS (
SELECT row_number() OVER ()
FROM arbitrary_table_having_enough_rows
limit 10000
)
...
另一种选择是拥有专门的序列表-这里有一个http://www.silota.com/docs/recipes/redshift-sequential-generate-series-numbers-time.html
的想法 ,使用多个分割结果。
`SELECT distinct split_part(split_part(replace(replace(replace(json_field,'{',''),'}','"',',i),': ',1) as value,` `split_part(split_part(replace(replace(replace(json_field,':',2) as key FROM table
JOIN schema.seq_1_to_100 as numbers
ON i <=regexp_count(json_field,':') `