如何从PostgreSQL中的Json数组中获取元素

时间:2015-01-08 06:50:18

标签: json postgresql arrays

我已经对此进行了大量搜索,但仍无法回答。我正在使用PostgreSQL。列名是"部分"以下示例中的列类型为json []。

我的专栏在数据库中显示如下:

sections
[{"name"      : "section1",
  "attributes": [{"attrkey1": "value1",
                  "attrkey2": "value2"},

                 {"attrkey3": "value3",
                  "attrkey4": "value4"}]
 },
 {"name"      : "section2",
  "attributes": [{"attrkey3": "value5",
                  "attrkey6": "value6"},

                 {"attrkey1": "value7",
                  "attrkey8": "value8"}]
 }]

它是json数组,我想得到" attrkey3"在我的结果中。为了从Json获取特定密钥,我可以使用json_extract_path_text(json_column, 'json_property'),它工作得很好。但我不知道如何从json []获得一些属性。

如果我谈到上面的例子,我想获得财产的价值" attrkey2"在我的结果中显示。我知道它是一个数组,所以它的工作方式可能与平常不同,例如:我的数组的所有值都将作为一个不同的行,所以我可能不得不编写子查询,但不知道如何做。

另外,我无法静态编写索引并从某个特定索引获取json元素的属性。我的查询将动态生成,所以我永远不会知道json数组中有多少元素。

我看到了一些静态示例,但我不知道如何在我的情况下实现它。有人可以告诉我如何在查询中执行此操作吗?

3 个答案:

答案 0 :(得分:17)

我不确定您是否有json[]json值的PostgreSQL数组)类型列,或json类型列,它似乎是一个JSON数组(比如你的例子。)

无论哪种情况,您都需要在查询之前扩展阵列。如果是json[],则需要使用unnest(anyarray);对于json类型列中的JSON数组,您需要使用json_array_elements(json)(和LATERAL联接 - 它们隐含在我的示例中):

select     t.id,
           each_section ->> 'name' section_name,
           each_attribute ->> 'attrkey3' attrkey3
from       t
cross join unnest(array_of_json) each_section
cross join json_array_elements(each_section -> 'attributes') each_attribute
where      (each_attribute -> 'attrkey3') is not null; 
-- use "where each_attribute ? 'attrkey3'" in case of jsonb


select     t.id,
           each_section ->> 'name' section_name,
           each_attribute ->> 'attrkey3' attrkey3
from       t
cross join json_array_elements(json_array) each_section
cross join json_array_elements(each_section -> 'attributes') each_attribute
where      (each_attribute -> 'attrkey3') is not null;

SQLFiddle

不幸的是,您不能对数据使用任何索引。您需要先修复架构,以便做到这一点。

答案 1 :(得分:3)

此外,如果array中有关键值地图数据:

select each_data -> 'value' as value3 
from t cross join jsonb_array_elements(t.sections -> 'attributes') each_attribute 
where each_attribute -> 'key' = '"attrkey3"'

我提到这一点,因为这个好的答案也为我的案子提供了一个完美的解决方案。顺便说一下,还要注意jsonb_array类型属性的jsonb ..方法。

答案 2 :(得分:0)

如果您希望访问单个元素,请使用json_array -> [index]

例如,如果您有json_arr=[1,2,3],则json_array -> 0将返回1