在Amazon Redshift中动态提取数据

问题描述

这是该列中的示例数据。我想动态提取仅与5相关联的值。

'{"2113":5,"2112":5,"2114":4,"2511":5}'

最终结构应为3行名称和值?

我尝试使用JSON提取功能,但没有帮助。谢谢

我想要的最终结果,

  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,':') `