Sql 从jsonb列获取特定值
我有一张桌子Sql 从jsonb列获取特定值,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,我有一张桌子Customer 客户ID(int) 客户名称(字符串) 客户订单(jsonB) 客户订单具有以下结构: { "nodeValue":[ { "key": "key1", "value": "value1" }, { "key": "key2", "value": "value2" }, { "key": "key3", "value": "value3" },
Customer
- 客户ID(int)
- 客户名称(字符串)
- 客户订单(jsonB)
客户订单
具有以下结构:
{
"nodeValue":[
{
"key": "key1",
"value": "value1"
},
{
"key": "key2",
"value": "value2"
},
{
"key": "key3",
"value": "value3"
},
{
"key": "key4",
"value": "value4"
},
{
"key": "key5",
"value": "value5"
}
]
}
我正在尝试获取行key='key3'和key='key4'
的nodeValue
的值
例如:返回'key3'和'key4'的值,其中key='key3'和key='key4'
我正在尝试做一些类似的事情:
SELECT value, value
from public.customers
where nodeValue.key3 = 'key3'
AND nodeValue.key4 = 'key4'
'{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}'
结果:
价值1
价值2
请注意使用运算符->>以文本形式获取值
我怀疑你真正想要的是
SELECT
(SELECT orders->>'value'
FROM json_array_elements(customerOrders->'nodeValue') AS orders
WHERE orders->>'key' = 'key3'
) AS value_key3,
(SELECT orders->>'value'
FROM json_array_elements(customerOrders->'nodeValue') AS orders
WHERE orders->>'key' = 'key4'
) AS value_key4
FROM public.customers;
但实际上,您的数据结构不适合此目的。使用具有键和值作为属性的对象,而不是具有键-值对的数组。有了它,您可以使用
SELECT
customerOrders->'nodeValue'->>'key3' AS value_key3,
customerOrders->'nodeValue'->>'key4' AS value_key4
FROM public.customers;
首先,您需要创建一个类型(或表) 然后你可以使用这个函数
SELECT
r_key1.value AS key1,
r_key2.value AS key2
FROM
customers c
JOIN LATERAL jsonb_populate_recordset(NULL::key_value_type, customerOrders -> 'nodeValue') r_key1
ON r_key1.key = 'key1'
JOIN LATERAL jsonb_populate_recordset(NULL::key_value_type, customerOrders -> 'nodeValue') r_key2
ON r_key2.key = 'key2'
或者使用jsonb\u to\u记录集
功能(不创建类型)
这是两个备选方案的结果
| key1 | key2 |
| ------ | ------ |
| value1 | value2 |
获取key='key3'和key='key4'
所在行的nodeValue
值
最佳使用:
要使它快速对于大型表,请使用索引支持它。理想情况下,一个jsonb\u路径\u ops
索引:
CREATE INDEX customer_nodeValue_idx ON customer
USING gin ((customerOrders->'nodeValue') jsonb_path_ops); -- parentheses required
见:
LATERAL
子查询中构建您的答案。应该是最简单、最干净、最快的。有关技术,请参见:
customerid
,以标识行。那是可选的
DBFIDLE(演示两者)
设计
您可以将臃肿的JSON布局简化为:
SELECT value, value
from public.customers
where nodeValue.key3 = 'key3'
AND nodeValue.key4 = 'key4'
'{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}'
或者至少:
'[
{
"key1": "value1"
},
{
"key2": "value2"
},
{
"key3": "value3"
},
{
"key4": "value4"
},
{
"key5": "value5"
}
]'
将使一切变得更简单、更小和更快。键=键3和键=键4不可能发生。你是说还是?不,这两个条件都应该是真的。一个
key
变量不能同时具有'key3'
和'Key4'
两个值。你真的是指key3='value3'和Key4='value4'
吗?Bergi完全正确,谢谢你的回答。但我正在寻找类似的东西:{key=“abs”,value=“1”},{key=“sup”,value=“1”},{key=“may”,value=“2”}。我想查询如下内容:选择值、来自客户的值,其中key=“abs”和key=“sup”结果应该有2个值:1,1感谢答案,我的输出可以返回记录数组。
SELECT c.customerid, o.values
FROM customer c
CROSS JOIN LATERAL (
SELECT ARRAY(
SELECT o.ord->>'value'
FROM jsonb_array_elements(c.customerOrders->'nodeValue') o(ord)
WHERE (o.ord->>'key' = 'key3' OR
o.ord->>'key' = 'key4')
)
) o(values)
WHERE c.customerOrders->'nodeValue' @> '[{"key": "key3"}]'
AND c.customerOrders->'nodeValue' @> '[{"key": "key4"}]';
'{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}'
'[
{
"key1": "value1"
},
{
"key2": "value2"
},
{
"key3": "value3"
},
{
"key4": "value4"
},
{
"key5": "value5"
}
]'