以下查询
SELECT jsonb_build_array(jsonb_build_object('use', 'Home'),
CASE WHEN 1 = 2 THEN jsonb_build_object('use', 'Work')
END)
产生
[{"use":"Home"},null]
我真正想要的时间
[{"use":"Home"}]
我该怎么做? json_strip_nulls()
对我不起作用。
答案 0 :(得分:1)
创建自定义函数似乎是最简单的方法。
create or replace function jsonb_build_array_without_nulls(variadic anyarray)
returns jsonb language sql immutable as $$
select jsonb_agg(elem)
from unnest($1) as elem
where elem is not null
$$;
select
jsonb_build_array_without_nulls(
jsonb_build_object('use', 'home'),
case when 1 = 2 then jsonb_build_object('use', 'work') end
)
jsonb_build_array_without_nulls
---------------------------------
[{"use": "home"}]
(1 row)
答案 1 :(得分:1)
通过使用像这样的PostgreSQL数组:
SELECT array_to_json(array_remove(ARRAY[jsonb_build_object('use', 'Home'),
CASE WHEN 1 = 2 THEN jsonb_build_object('use', 'Work') END], null))
会产生:
[{"use": "Home"}]
同时,请确保:
SELECT array_to_json(array_remove(ARRAY[jsonb_build_object('use', 'Home'),
CASE WHEN 1 = 2 THEN jsonb_build_object('use', 'Work') END,
jsonb_build_object('real_use', 'NotHome')], null))
产生:
[{"use": "Home"},{"real_use": "NotHome"}]
答案 2 :(得分:0)
我假设此查询是通过某种方式动态生成的。如果您控制着SQL的生成,也可以改用ARRAY_AGG(...) FILTER(...)
,这取决于实际查询,可能比使用所有其他array conversion functions suggested by Patrick更为方便。
SELECT (
SELECT json_agg(v) FILTER (WHERE v IS NOT NULL)
FROM (
VALUES
(jsonb_build_object('use', 'Home')),
(CASE WHEN 1 = 2 THEN jsonb_build_object('use', 'Work') END)
) t (v)
)
或者:
SELECT (
SELECT json_agg(v)
FROM (
VALUES
(jsonb_build_object('use', 'Home')),
(CASE WHEN 1 = 2 THEN jsonb_build_object('use', 'Work') END)
) t (v)
WHERE v IS NOT NULL
)
答案 3 :(得分:0)
可以解决此问题的另一种方法是:
SELECT jsonb_build_array(
jsonb_build_object('use', 'Home'),
CASE
WHEN 1 = 2 THEN jsonb_build_object('use', 'Work')
ELSE '"null"'
END
) - 'null'
(不幸的是,在Postgres或大多数其他数据库中,仅靠null
本身并不能做很多事情)
在上述情况下,'"null"'
几乎可以替换为不会被误认为数组中实时数据的任何唯一字符串。我不会使用数字,因为- 0
实际上会尝试从数组中删除第一项,而不是数组中的数字。但您可能可以使用'"0"'
,并根据需要使用- '0'
之类的内容删除。
对于不使用CASE
的用户,可以使用COALESCE
将空值转换为所需的字符串(alas,否NVL
,IFNULL
或ISNULL
在postgres中,但至少COALESCE
是可移植的)