查询 JSON 列中的数组元素

Posted

技术标签:

【中文标题】查询 JSON 列中的数组元素【英文标题】:Query for element of array in JSON column 【发布时间】:2013-11-03 06:57:15 【问题描述】:

最近升级到使用 PostgreSQL 9.3.1 以利用 JSON 功能。在我的表中,我有一个 json 类型的列,其结构如下:


   "id": "123",
   "name": "foo",
   "emails":[
      
        "id": "123",
        "address": "somethinghere"
      ,
      
        "id": "456",
        "address": "soemthing"
      
   ]
 

这只是用于问题目的的虚拟数据。

是否可以根据 id 查询 emails 数组中的特定项目? 差不多:“return email where id=123)”?

【问题讨论】:

【参考方案1】:

是的,这是可能的:

SELECT *
FROM   tbl t, json_array_elements(t.json_col->'emails') AS elem
WHERE  elem->>'id' = 123;

tbl 是您的表名,json_col 是 JSON 列的名称。

此相关答案中的更多详细信息:

How do I query using fields inside the new PostgreSQL JSON datatype?

有关此相关答案最后一段中隐含的CROSS JOIN LATERAL 的更多信息:

PostgreSQL unnest() with element number

支持这种查询的索引:

Index for finding an element in a JSON array

【讨论】:

这是迄今为止我看到的此类问题的最佳答案。 @ErwinBrandstetter 很抱歉,您能帮我解决这个问题吗:***.com/q/49532773(提前致谢!)【参考方案2】:

使用 Postgres 9.4+ 中的 JSONB 列,您可以使用包含运算符 @> 来查询数组中的元素:

SELECT * FROM jsontest WHERE data @> ' "emails": [ "id": "123" ] ';

更多详情请见Query for array elements inside JSON type。

这是一个工作示例:

CREATE TABLE jsontest(data JSONB NOT NULL);
INSERT INTO jsontest VALUES (
  '
     "name": "foo",
     "id": "123",
     "emails": 
     [
       
         "address": "somethinghere",
         "id": "123"
       ,
       
         "address": "soemthing",
         "id": "456"
       
     ]
  '
);
SELECT * FROM jsontest WHERE data @> ' "emails": [ "id": "123" ] ';

data
----
"id": "123", "name": "foo", "emails": ["id": "123", "address": "somethinghere", "id": "456", "address": "soemthing"]

(1 行)

【讨论】:

如何通过 id 123 删除地址? delete FROM jsontest WHERE data @> ' "emails": [ "id": "123" ] ';【参考方案3】:

偶然看到这个帖子,发现可以这样直接查询表:

SELECT *
FROM   table_name, json_array_elements(json_column) AS data
WHERE  data->>'id' = 123;

省略这部分:

json_array_elements(t.json_col->'emails')

【讨论】:

这是超级超级有用的,我一直在努力使用 CTE 来尝试让它发挥作用,这很好地解决了我的需求。谢谢!【参考方案4】:

你可以这么简单:

SELECT * FROM table WHERE emails->>'id' = '123';

您似乎将 id 存储为字符串,如果它是一个整数,您可以这样做:

SELECT *  from table WHERE cast(emails->>'id' as integer ) = 123  ;

或者你可以得到所有 id > 10 的行

SELECT *  from table WHERE cast(emails->>'id' as integer ) > 10  ;

【讨论】:

我已经在 Postgres 9.4.4 上尝试过,但它不起作用:

以上是关于查询 JSON 列中的数组元素的主要内容,如果未能解决你的问题,请参考以下文章

如何查询数据库以查找包含来自多选 (Laravel) 的 json 数据的列中的元素

使用 JPA 原生查询在 jsonb(JSON 数组)列中查询

查询嵌套 JSON 数组 PostgreSQL 中的所有元素

如何使用 AND 查询 MYSQL 中的 JSON 数组

如何查询同一个json对象数组中的多个属性?

MySQL_关于JSON数据的查询