如何仅从 postgres 获取特定密钥的 jsonb?



我知道您可以使用这样的东西从 postgres 中的 jsonb 中删除密钥

select '{"a": 1, "b": 2, "c":3}'::jsonb -'a';
?column?
----------
{"b": 2 "c":3}
(1 row)

有没有办法只抓取特定的钥匙?比如说我只想获取'a'键的键值对。

像这样的东西?

select '{"a": 1, "b": 2}'::jsonb + 'a' + 'b';
?column?
----------
{"a": 1, "b": 2}
(1 row)

编辑:将示例更改为显示我想从jsonb中获取多个键值对,而不仅仅是一对。

您可以像这样轻松地过滤到单个键:

jsonb_object(ARRAY[key, jsonb_data -> key])

。或者,您可以筛选到多个键:

(SELECT jsonb_object_agg(key, value) FROM jsonb_each(jsonb_data) WHERE key IN ('a', 'b'))

或者在更复杂的条件下,如果需要:

(
SELECT jsonb_object_agg(key, value)
FROM jsonb_each(jsonb_data)
WHERE
key NOT LIKE '__%'
AND jsonb_typeof(value) != 'null'
)

只需阅读文档即可轻松回答此类问题。

我实际上发现这种方式有效。

select jsonb_build_object('key', column->'key') from table;

参考: https://www.reddit.com/r/PostgreSQL/comments/73auce/new_user_to_postgres_can_i_grab_multiple_keys_of/

你可以这样做

SELECT jsonb_column->>'key_name_here' as 'alias_name_as_you_like' from table_name

在上面问的查询的情况下,它将是

select '{"a": 1, "b": 2, "c":3}'::jsonb->>'a'

释义情况

我们有一个 JSON 值和多个键,ac

select '{"a": 1, "b": 2, "c":3}'::jsonb - '{a,c}'::text[];

-是一个整洁的运算符,但给了我们与您想要的相反

{"b": 2}

解决方案是将其包装在array(select jsonb_object_keys(...))中并再次执行-

select '{"a": 1, "b": 2, "c":3}'::jsonb - array(select jsonb_object_keys('{"a": 1, "b": 2, "c":3}'::jsonb - '{a,c}'::text[]));

你会得到一个只有这些键ac的 JSON

{"a": 1, "c": 3}

您可以像这样获得值:

select '{"a": 1, "b": 2}'::jsonb-> 'a';

如果必须,您可以手动将其转换回jsonb,或者通过数组,hstore或其他中间类型。这是"手动"方式

select ('{ "a": '||('{"a": 1, "b": 2}'::jsonb->'a')::text||'}')::jsonb

如果要筛选包含 JSONB 文档的多行:

-- Let's generate rows with JSONB column:
WITH s AS (SELECT generate_series(1, 100) num),
g AS (SELECT num, jsonb_build_object('a', s.num, 'b', s.num * 2) obj FROM s),
-- A "filter" adding (in my example only keys of "filter" document remain in result rows)
j AS (SELECT '{"a": "int", "c": "string"}'::jsonb AS filter),
a AS (SELECT (ARRAY(SELECT jsonb_object_keys(filter))) AS ar FROM j),
-- Useless keys removing
o AS (SELECT jsonb_object_agg(l.key, l.value) obj
FROM g, LATERAL jsonb_each(g.obj) l, a 
WHERE l.key = ANY(a.ar)
GROUP BY num)
SELECT * FROM o ORDER BY obj->'a';
Begin;
CREATE TEMPORARY TABLE test (id  serial, jdoc jsonb);
insert into test(jdoc) values('{"a": {"b":"foo"}}');
insert into test(jdoc) values('{"a": "test"}');
insert into test(jdoc) values('{"a":[2,3,4]}');
insert into test(jdoc) values('{"b":[2,3,4]}');
commit;

select (jdoc->'a') from test where jdoc ? 'a'
将获取所有特定键的值.
如果你想要特定键的 JSONB:select jdoc from test where jdoc ? 'a'

最新更新