简体   繁体   English

PostgreSQL 如何按值查询 jsonb?

[英]PostgreSQL how to query jsonb by a value?

SELECT * FROM some_table;

I can query to get the following results:我可以查询得到以下结果:

{
    "sku0": {
        "Id": "18418",
        "Desc": "yes"
    },
    "sku1": {
        "Id": "17636",
        "Desc": "no"
    },
    "sku2": {
        "Id": "206714",
        "Desc": "yes"
    },
    "brand": "abc",
    "displayName": "something"
}

First, the number of skus is not fixed.首先,skus的数量不是固定的。 It may be sku0, sku1, sku2, sku3, sku4 ... but they all start with sku .它可能是 sku0, sku1, sku2, sku3, sku4 ...但它们都以sku开头。

Then, I want to query Id with 17636 and determine whether its value of Desc is yes or no.然后,我想用17636查询 Id 并确定其Desc 的值是是还是否。 After reading the PostgreSQL JSON Functions and Operators documentation , Depressing I didn't find a good way.看了PostgreSQL JSON Functions and Operators 文档后,郁闷我没有找到好的方法。

I can convert the result into a Python dictionary, and then use python's method can easily achieve my requirements.我可以将结果转换成Python字典,然后使用python的方法可以轻松实现我的要求。

If the requirements can also be achieved with postgresql statements, which method is more recommended than the Python dictionary?如果用postgresql语句也能达到要求,比Python字典更推荐哪种方法?

I am not sure I completely understand what the result is you want.我不确定我是否完全理解你想要的结果。 But if you want to filter on the Id, you need to unnest all the elements inside the JSON column:但是如果要过滤 Id,则需要取消嵌套 JSON 列中的所有元素:

select d.v ->> 'Desc' as description
from the_table t
  cross join jsonb_each(t.data) as d(k,v)
where d.v ->> 'Id' = '17636'

You could use the new jsonpath notation of PostgreSQL v12:您可以使用 PostgreSQL v12 的新 jsonpath 表示法:

SELECT data @@ '$.* ? (@.Id == "17636").Desc == "yes"'
FROM some_table;

That will start with the root of data ( $ ), find any attribute in it ( * ), filter only those attributes that contain an Id with value "17636" , get their Desc attribute and return TRUE only if that attribute is "yes" .这将从data的根 ( $ ) 开始,查找其中的任何属性 ( * ),仅过滤包含值为"17636"Id那些属性,获取其Desc属性并仅在该属性为"yes"返回TRUE .

Nice, isn't it?不错,不是吗?

This will probably give you what you need.这可能会给你你需要的东西。

select value->>'Desc' from jsonb_each('{
    "sku0": {
        "Id": "18418",
        "Desc": "yes"
    },
    "sku1": {
        "Id": "17636",
        "Desc": "no"
    },
    "sku2": {
        "Id": "206714",
        "Desc": "yes"
    },
    "brand": "abc",
    "displayName": "something"
}'::jsonb)
where key like 'sku%'
and value->>'Id'='17636'

Best regards,此致,
Bjarni比亚尼

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM