如何有条件地将元素添加到 jsonb 数组?
How can I conditionally add elements to a jsonb array?
有没有一种方法可以有条件地将元素添加到 postgres jsonb 数组中?我正在尝试构造一个数组以添加到更大的对象中,其中大多数元素始终是必需的,但我希望其中一些元素是可选的。
举个简单的例子:
select jsonb_build_array(
jsonb_build_object('a', a),
jsonb_build_object('b', b),
jsonb_build_object('c', c),
case when a + b <> c then
jsonb_build_object('error', c - (a + b))
end
) from ( values (2, 2, 5) ) as things (a,b,c);
这在 a+b<>c 时工作正常,但当 a+b=c 我在 array.e.g.
中得到一个空值
sophia=> \i ~/cc/dpdb/migration/foo.sql
jsonb_build_array
----------------------------------------------
[{"a": 2}, {"b": 2}, {"c": 5}, {"error": 1}]
(1 row)
sophia=> \i ~/cc/dpdb/migration/foo.sql
jsonb_build_array
--------------------------------------
[{"a": 2}, {"b": 2}, {"c": 4}, null]
(1 row)
sophia=>
有没有办法添加不带 null 的元素,或者如果添加,删除 null?显然,我可以将整个块放在一个案例中并复制前几行,但这会相当丑陋和冗长。有 jsonb_strip_nulls 但这只适用于对象而不是数组。
您必须使用第二个步骤,因为您无法在语法中创建 "no element"。要么你真的用两个不同的数组创建来区分这两种情况,要么你必须在之后有条件地调整创建的数组:
SELECT
CASE WHEN a + b <> c THEN
my_array || jsonb_build_object('error', c - (a + b))
ELSE
my_array
END
FROM (
select
a, b, c,
jsonb_build_array(
jsonb_build_object('a', a),
jsonb_build_object('b', b),
jsonb_build_object('c', c)
) AS my_array
from ( values (2, 2, 5), (2, 2, 4) ) as things (a,b,c)
) s
有没有一种方法可以有条件地将元素添加到 postgres jsonb 数组中?我正在尝试构造一个数组以添加到更大的对象中,其中大多数元素始终是必需的,但我希望其中一些元素是可选的。
举个简单的例子:
select jsonb_build_array(
jsonb_build_object('a', a),
jsonb_build_object('b', b),
jsonb_build_object('c', c),
case when a + b <> c then
jsonb_build_object('error', c - (a + b))
end
) from ( values (2, 2, 5) ) as things (a,b,c);
这在 a+b<>c 时工作正常,但当 a+b=c 我在 array.e.g.
中得到一个空值sophia=> \i ~/cc/dpdb/migration/foo.sql
jsonb_build_array
----------------------------------------------
[{"a": 2}, {"b": 2}, {"c": 5}, {"error": 1}]
(1 row)
sophia=> \i ~/cc/dpdb/migration/foo.sql
jsonb_build_array
--------------------------------------
[{"a": 2}, {"b": 2}, {"c": 4}, null]
(1 row)
sophia=>
有没有办法添加不带 null 的元素,或者如果添加,删除 null?显然,我可以将整个块放在一个案例中并复制前几行,但这会相当丑陋和冗长。有 jsonb_strip_nulls 但这只适用于对象而不是数组。
您必须使用第二个步骤,因为您无法在语法中创建 "no element"。要么你真的用两个不同的数组创建来区分这两种情况,要么你必须在之后有条件地调整创建的数组:
SELECT
CASE WHEN a + b <> c THEN
my_array || jsonb_build_object('error', c - (a + b))
ELSE
my_array
END
FROM (
select
a, b, c,
jsonb_build_array(
jsonb_build_object('a', a),
jsonb_build_object('b', b),
jsonb_build_object('c', c)
) AS my_array
from ( values (2, 2, 5), (2, 2, 4) ) as things (a,b,c)
) s