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:

我使用 LATERALLEFT 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') #>> '{}