PostgreSQL jsonb_path_query 删除结果而不是返回空值
PostgreSQL jsonb_path_query removes result instead of returning null value
举例table:
create table example
(
id serial not null
constraint example_pk
primary key,
data json not null
);
和数据
INSERT INTO public.example (id, data) VALUES (1, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]');
INSERT INTO public.example (id, data) VALUES (2, '[{"key": "1", "value": "val1"}]');
INSERT INTO public.example (id, data) VALUES (3, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]');
id
data
1
[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]
2
[{"key": "1", "value": "val1"}]
3
[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]
我想查询key = 2的数据列中的value字段
我目前使用的查询是这样的:
SELECT id,
jsonb_path_query(
TO_JSONB(data),
'$[*] ? (@.key == "2").value'::JSONPATH
)::VARCHAR AS values
FROM example
我希望结果是:
id
values
1
"val2"
2
null
3
"val2"
但实际结果是:
id
values
1
"val2"
3
"val2"
jsonb_path_query
的空输出被省略是什么原因?我如何让它按照我期望的方式运行?
根据 PostgreSQL documentation 过滤器充当 WHERE
条件
When defining the path, you can also use one or more filter expressions that work similar to the WHERE clause in SQL. A filter expression begins with a question mark and provides a condition in parentheses:
我使用 LATERAL
和 LEFT JOIN
成功实现了您的需求
SELECT id,
*
FROM example left join
LATERAL jsonb_path_query(
TO_JSONB(data),
'$[*] ? (@.key == "2").value'::JSONPATH)
on true;
结果
id | id | data | jsonb_path_query
----+----+----------------------------------------------------------------+------------------
1 | 1 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] | "val2"
2 | 2 | [{"key": "1", "value": "val1"}] |
3 | 3 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] | "val2"
(3 rows)
如果您想要路径表达式的结果,您需要 jsonb_path_query_first()
:
SELECT id,
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') AS values
FROM example
请注意,此 returns 是一个 jsonb
值。如果您想要 text
值,请使用:
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') #>> '{}
举例table:
create table example
(
id serial not null
constraint example_pk
primary key,
data json not null
);
和数据
INSERT INTO public.example (id, data) VALUES (1, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]');
INSERT INTO public.example (id, data) VALUES (2, '[{"key": "1", "value": "val1"}]');
INSERT INTO public.example (id, data) VALUES (3, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]');
id | data |
---|---|
1 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] |
2 | [{"key": "1", "value": "val1"}] |
3 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] |
我想查询key = 2的数据列中的value字段
我目前使用的查询是这样的:
SELECT id,
jsonb_path_query(
TO_JSONB(data),
'$[*] ? (@.key == "2").value'::JSONPATH
)::VARCHAR AS values
FROM example
我希望结果是:
id | values |
---|---|
1 | "val2" |
2 | null |
3 | "val2" |
但实际结果是:
id | values |
---|---|
1 | "val2" |
3 | "val2" |
jsonb_path_query
的空输出被省略是什么原因?我如何让它按照我期望的方式运行?
根据 PostgreSQL documentation 过滤器充当 WHERE
条件
When defining the path, you can also use one or more filter expressions that work similar to the WHERE clause in SQL. A filter expression begins with a question mark and provides a condition in parentheses:
我使用 LATERAL
和 LEFT JOIN
SELECT id,
*
FROM example left join
LATERAL jsonb_path_query(
TO_JSONB(data),
'$[*] ? (@.key == "2").value'::JSONPATH)
on true;
结果
id | id | data | jsonb_path_query
----+----+----------------------------------------------------------------+------------------
1 | 1 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] | "val2"
2 | 2 | [{"key": "1", "value": "val1"}] |
3 | 3 | [{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}] | "val2"
(3 rows)
如果您想要路径表达式的结果,您需要 jsonb_path_query_first()
:
SELECT id,
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') AS values
FROM example
请注意,此 returns 是一个 jsonb
值。如果您想要 text
值,请使用:
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') #>> '{}