我如何 select 仅来自 Postgres 中的 jsonb 类型的特定键值
How do I select only a specific key's value from jsonb type in Postgres
我有一个 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
字段,该数组有一个名为 slug
的 key
,这样当我对 [=29] 执行 select 查询时=],我从列中得到这个特定的值。对于上一行,当我执行 select name, slug, price from table
时,我应该得到 med1, otc7087, 100
作为输出。我无法为这个东西建立查询。我可以获得所有键或所有值,但我如何 select 同一 select 查询中的特定键?
或者我如何 select 只是 table 中的 slugs
?那会回答。
您似乎想要在 json 数组的所有元素中搜索具有给定键的特定值的对象,然后 return 如果匹配则搜索另一个键的值。
像这样的东西就可以了:
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';
即table 中的 select,将数组解压缩为一个联接,通过查找具有值 json 键 key
来过滤所需对象的联接 table =13=],return 找到 select
子句中的 json 键 value
的值。
如果您想要来自同一个 json 对象的多个不同值,您需要多个连接,每个所需值一个。
这是一种非常丑陋的存储可变 key/value 格式数据的方法。我建议像这样存储:
{"unit_type": {"value": "Tablet", "display_name": "Unit Type"}, ...}
您可以在哪里实际查找密钥。
我相信你的 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 转换为 table,键、值、display_name 作为列,然后您可以对其进行任何类型的查询,它也适用于提取键,而@Craig Ringer 建议您无法将其转换为 table 之类的东西,并触发复杂的 select 查询,例如 not in , != , range queries , ilike 将非常困难并且可能表现不佳。
我有一个 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
字段,该数组有一个名为 slug
的 key
,这样当我对 [=29] 执行 select 查询时=],我从列中得到这个特定的值。对于上一行,当我执行 select name, slug, price from table
时,我应该得到 med1, otc7087, 100
作为输出。我无法为这个东西建立查询。我可以获得所有键或所有值,但我如何 select 同一 select 查询中的特定键?
或者我如何 select 只是 table 中的 slugs
?那会回答。
您似乎想要在 json 数组的所有元素中搜索具有给定键的特定值的对象,然后 return 如果匹配则搜索另一个键的值。
像这样的东西就可以了:
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';
即table 中的 select,将数组解压缩为一个联接,通过查找具有值 json 键 key
来过滤所需对象的联接 table =13=],return 找到 select
子句中的 json 键 value
的值。
如果您想要来自同一个 json 对象的多个不同值,您需要多个连接,每个所需值一个。
这是一种非常丑陋的存储可变 key/value 格式数据的方法。我建议像这样存储:
{"unit_type": {"value": "Tablet", "display_name": "Unit Type"}, ...}
您可以在哪里实际查找密钥。
我相信你的 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 转换为 table,键、值、display_name 作为列,然后您可以对其进行任何类型的查询,它也适用于提取键,而@Craig Ringer 建议您无法将其转换为 table 之类的东西,并触发复杂的 select 查询,例如 not in , != , range queries , ilike 将非常困难并且可能表现不佳。