如何在Postgres中仅从jsonb类型中选择特定键的值

时间:2015-10-25 14:34:34

标签: postgresql jsonb

我有一个jsonb列,其中包含以下数据。

[
   {"key": "unit_type", "value": "Tablet", "display_name": "Unit Type"},
   {"key": "pack_type", "value": "Packet", "display_name": "Pack Type"},
   {"key": "units_in_pack", "value": "60", "display_name": "Units in Pack"},
   {"key": "item_unit", "value": "", "display_name": "Item unit"},
   {"key": "item_size", "value": "1", "display_name": "Item Size"}, 
   {"key": "details", "value": "", "display_name": "Details"},
   {"key": "slug", "value": "otc7087", "display_name": "Slug"}
]

我想从数组中获取value字段,其中key名为slug,因此当我对表执行select查询时,我从中获取此特定值柱。对于我执行select name, slug, price from table时的上一行,我应该将med1, otc7087, 100作为输出。我无法为此事构建查询。我可以获取所有键或所有值,但如何在同一个选择查询中选择特定的键?

或者我只是如何从表中选择slugs?那会回答。

2 个答案:

答案 0 :(得分:6)

我相信你的json更有条理, 试试jsonb_to_recordset

代表:

select * from json_to_recordset('[
   {"key": "unit_type", "value": "Tablet", "display_name": "Unit Type"},
   {"key": "pack_type", "value": "Packet", "display_name": "Pack Type"},
   {"key": "units_in_pack", "value": "60", "display_name": "Units in Pack"},
   {"key": "item_unit", "value": "", "display_name": "Item unit"},
   {"key": "item_size", "value": "1", "display_name": "Item Size"}, 
   {"key": "details", "value": "", "display_name": "Details"},
   {"key": "slug", "value": "otc7087", "display_name": "Slug"}
]') as x(key int, value text, display_name text);

它会将jsonb转换为带有key,value,display_name作为列的表,然后你可以触发任何类型的查询,它也适用于提取键,而@Craig Ringer建议你无法转换它像表格一样进入表格并解决复杂的选择查询,如不在,!=,范围查询,ilike将非常困难,可能性能较差。

答案 1 :(得分:1)

您似乎想要搜索具有给定键的特定值的对象的json数组的所有元素,然后返回另一个键的值(如果匹配)。

这样的事情可以解决问题:

WITH my_table(jsonblob) AS (VALUES('[
   {"key": "unit_type", "value": "Tablet", "display_name": "Unit Type"},
   {"key": "pack_type", "value": "Packet", "display_name": "Pack Type"},
   {"key": "units_in_pack", "value": "60", "display_name": "Units in Pack"},
   {"key": "item_unit", "value": "", "display_name": "Item unit"},
   {"key": "item_size", "value": "1", "display_name": "Item Size"}, 
   {"key": "details", "value": "", "display_name": "Details"},
   {"key": "slug", "value": "otc7087", "display_name": "Slug"}
]'::jsonb))
SELECT elem ->> 'value'
FROM my_table
CROSS JOIN LATERAL jsonb_array_elements(jsonblob) elem
WHERE (elem ->> 'key') = 'slug';

即。从表中选择,将数组解压缩到连接中,通过查找值为key的json键slug来过滤所需对象的连接表,并返回json键的值{{1在value子句中找到。

如果您想要来自同一个json对象的多个不同值,则需要多个连接,每个连接需要一个。

这是存储变量键/值格式数据的一种非常难看的方式。我建议存储如下:

select

你可以在那里查找按键。