使用Postgresql查询检索JSON数组的前N条记录

时间:2016-06-30 15:34:46

标签: json postgresql

自verison 9.3以来,PostgreSQL有一些本地JSON operations。假设您有一个my_table表,jsonmy_json_col,结构如下:

[
  { "id": 1, "some_field": "blabla" },
  { "id": 2, "some_field": "foo" }
  ...
]

要检索my_json_col的第n个元素,您可以执行以下操作:SELECT my_json_col->n FROM my_table WHERE ...。因此,如果n = 1,查询将在我的示例中返回"id": 2记录。

我想检索前n个元素,例如如果n = 2查询应返回我示例中的前两个记录。这可能吗?

3 个答案:

答案 0 :(得分:3)

我认为你需要convert the JSON array to a regular Postgres array,然后再分一杯:

select (array_agg(e))[2:3]
from (select json_array_elements('[{"id":1},{"id":2},{"id":3},{"id":4}]'::json)) x(e);

如果您需要结果为JSON,可以使用array_to_json

select array_to_json((array_agg(e))[2:3])
from (select json_array_elements('[{"id":1},{"id":2},{"id":3},{"id":4}]'::json)) x(e); 

答案 1 :(得分:3)

在PostgreSQL 12中,您可以执行以下操作:

SELECT jsonb_path_query_array('["a","b","c","d","e","f"]', '$[0 to 3]');
 jsonb_path_query_array
------------------------
 ["a", "b", "c", "d"]
(1 row)

答案 2 :(得分:0)

对于那些在尝试同样的事情时会绊倒的人。这就是我所面临的

我遇到了类似的问题,我需要来自包含数组的 jsonb 字段的 N 结果。我需要的结果是表的所有字段和满足条件的数据字段中的N个数据。

在一次又一次地经历这个之后,我发现接受的答案聚合了行。所以如果你有一张桌子

<头>
id 类型 数据 状态
1 员工 {{"age": 29, "name": "EMP 1"}, {"age": 30, "name": "EMP 2"},...} 活跃
2 经理 {{"age": 28, "name": "MNG 1"}, {"age": 30, "name": "MNG 2"},...} 活跃

然后你运行查询

select (array_agg(e))[2:3]
from (select json_array_elements(data::json) from <table>) x(e);

那么输出将是

<头>
数据
{{"age": 30, "name": "EMP 2"}, {"age": 28, "name": "MNG 1"}}

在我的情况下不需要,我需要的是满足条件的每一行的 n 个数据,例如

<头>
数据
{{"age": 29, "name": "EMP 1"},{"age": 30, "name": "EMP 2"}}
{{"age": 28, "name": "MNG 1"},{"age": 30, "name": "MNG 2"}}

所以在稍微搜索并浏览了@Paul A Jungwirth 提供的 link 之后 在接受的答案中。我发现这也可以通过

来实现

select (ARRAY(select json_array_elements_text(data::json)))[0:2]

并且结果将为您提供来自满足条件的jsonb字段的n个数据,您也可以使用它访问其他字段。比方说你想要这个表中的 id 和 n 个数据,那么你可以通过在选择查询中添加 id 来做到这一点。 (我无法在已接受答案的查询中获得“id”)

select id, (ARRAY(select json_array_elements(data::json)))[0:2] from table where condition

将给出输出

<头>
id 数据
1 {{"age": 29, "name": "EMP 1"},{"age": 30, "name": "EMP 2"}}
2 {{"age": 28, "name": "MNG 1"},{"age": 30, "name": "MNG 2"}}

希望这对某人有所帮助。