[英]Get specific values from a jsonb column
我有一個表Customer
customerOrders
具有以下結構:
{
"nodeValue":[
{
"key": "key1",
"value": "value1"
},
{
"key": "key2",
"value": "value2"
},
{
"key": "key3",
"value": "value3"
},
{
"key": "key4",
"value": "value4"
},
{
"key": "key5",
"value": "value5"
}
]
}
我正在嘗試獲取行key = 'key3' AND key = 'key4'
的nodeValue
的值。
例如:返回 'key3' 和 'key4' 的值, WHERE key = 'key3' AND key = 'key4'
。
我正在嘗試執行以下操作:
SELECT value, value
from public.customers
where nodeValue.key3 = 'key3'
AND nodeValue.key4 = 'key4'
with orders as
(
select jsonb_array_elements(customerOrders->'nodeValue') as orders
from customers
)
select orders->'value' as val
from orders
where
orders->>'key' = 'key3'
or orders->>'key' = 'key4';
結果:
值1
值2
請注意使用運算符 ->> 以文本形式獲取值
獲取
key = 'key3' AND key = 'key4'
的行的nodeValue
值。
最好使用jsonb
“包含”運算符@>
:
SELECT customerid, customerOrders->'nodeValue'
FROM customer
WHERE customerOrders->'nodeValue' @> '[{"key": "key3"}]'
AND customerOrders->'nodeValue' @> '[{"key": "key4"}]';
為了使大表快速支持它,請使用索引。 理想情況下是一個jsonb_path_ops
索引:
CREATE INDEX customer_nodeValue_idx ON customer
USING gin ((customerOrders->'nodeValue') jsonb_path_ops); -- parentheses required
看:
你的問題的最新版本有點棘手:
返回“KEY3”和“KEY4”的價值
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"}]';
首先過濾符合上述條件的行(使用快速索引查找)。 然后取消嵌套 JSON 文檔並在LATERAL
子查詢中構建您的答案。 應該是最簡單、最干凈和最快的。 有關技術,請參閱:
我將customerid
添加到兩個查詢的結果中以標識行。 那是可選的。
db<> 在這里小提琴(展示兩者)
您可以將臃腫的 JSON 布局簡化為:
'{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}'
或者至少:
'[
{
"key1": "value1"
},
{
"key2": "value2"
},
{
"key3": "value3"
},
{
"key4": "value4"
},
{
"key5": "value5"
}
]'
將使一切變得更簡單、更小、更快。
我懷疑你真正想要的是
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;
首先你需要創建一個類型(或表)
CREATE TYPE key_value_type AS (
key text,
value text
);
然后你可以使用jsonb_populate_recordset函數
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_to_recordset
函數(不創建類型)
SELECT
r_key1.value AS key1,
r_key2.value AS key2
FROM
customers c
JOIN LATERAL jsonb_to_recordset(customerOrders -> 'nodeValue') AS r_key1 (key text,
value text) ON r_key1.key = 'key1'
JOIN LATERAL jsonb_to_recordset(customerOrders -> 'nodeValue') AS r_key2 (key text,
value text) ON r_key2.key = 'key2'
這是兩種選擇的結果;
| key1 | key2 |
| ------ | ------ |
| value1 | value2 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.