WHERE 条件过滤嵌套对象或数组中的 JSON 数据

问题描述 投票:0回答:1

我在 PostgreSQL 数据库中有一个表,包含 6 行 JSON 数据:

select * from js.orders;

退货

id |                                                info                                                
----+----------------------------------------------------------------------------------------------------
  1 | { "customer": "Kapil", "items": {"product": "Heineken","qty": 6}}
  2 | { "customer": "Satyen", "items": {"product": "Heineken","qty": 18}}
  3 | { "customer": "Rekha", "items": {"product": "Carlsberg","qty": 24}}
  4 | { "customer": "Madhuri", "items": {"product": "Kalyani","qty": 12}}
  5 | { "customer": "Srinivas", "items": {"product": "Kingfisher Strong","qty": 12}}
  6 | { "customer": "Saina", "items": [{"product": "Bira91","qty": 6},{"product": "Kalyani","qty": 6} ]}
(6 rows)

以下带有“where”条件的“select”查询:

SELECT info ->> 'customer' AS customer FROM js.orders WHERE info -> 'items' ->> 'product' = 'Heineken';

返回正确的两行:

customer 
----------
 Kapil
 Satyen
(2 rows)

但是,以下查询应返回两行:

SELECT info ->> 'customer' AS customer FROM js.orders WHERE info -> 'items' ->> 'product' = 'Kalyani';

但只返回一行:

    customer     
-----------------
 Madhuri
(1 row)

显然,“customer”:“Sania”行有一个“items”列表而不是单个“items”导致了这个问题。我应该如何修改查询以便返回正确的行数。或者是否必须重新格式化数据。

sql json postgresql where-clause jsonpath
1个回答
0
投票

您的第一个问题是,您将结构化数据存储为 JSON 文档,而不是关系设计中的普通列,这对于存储和查询来说会更加高效。

您的第二个问题是您无需改变所述 JSON 文档的结构。有些有一个

object,有些有一个 array 作为键“items”的值。 (没有一个有“列表”,这在JSON术语中不存在。)使查询更加复杂。

虽然坚持了你不幸的设计,但使用

jsonpath

 运算符 
@?
的查询可以工作,因为它以默认的“宽松”模式处理给定路径上的对象
数组:

SELECT info ->> 'customer' AS customer FROM orders WHERE info -> 'items' @? '$.product ? (@ == "Kalyani")';
仅查看

对象,就像您的原始查询一样:

SELECT id, info ->> 'customer' AS customer FROM orders WHERE info -> 'items' @? 'strict $.product ? (@ == "Kalyani")';

小提琴

需要 Postgres 12 或更高版本,其中添加了 SQL/JSON 路径语言。

您可能需要索引支持。参见:

  • Postgres jsonb 查询动态值
© www.soinside.com 2019 - 2024. All rights reserved.