处理 jsonb_array_elements 中的 Null
Handle Null in jsonb_array_elements
我有 2 tables a 和 b
Table一个
id | name | code
VARCHAR VARCHAR jsonb
1 xyz [14, 15, 16 ]
2 abc [null]
3 def [null]
Tableb
id | name | code
1 xyz [16, 15, 14 ]
2 abc [null]
我想找出代码与相同 ID 和名称不匹配的地方。我对 b 中的代码列进行排序 b/c 我知道它相同但排序不同
SELECT a.id,
a.name,
a.code,
c.id,
c.name,
c.code
FROM a
FULL OUTER JOIN ( SELECT id,
name,
jsonb_agg(code ORDER BY code) AS code
FROM (
SELECT id,
name,
jsonb_array_elements(code) AS code
FROM b
GROUP BY id,
name,
jsonb_array_elements(code)
) t
GROUP BY id,
name
) c
ON a.id = c.id
AND a.name = c.name
AND COALESCE (a.code, '[]'::jsonb) = COALESCE (c.code, '[]'::jsonb)
WHERE (a.id IS NULL OR c.id IS NULL)
我在这种情况下的回答应该只有 return id = 3 b/c 它不在 b table 但我的查询也是 returning id = 2 b/c 我在内部子查询中没有很好地处理 null 情况
我如何处理内部子查询中的空用例?
<@
运算符检查左侧数组的所有元素是否都出现在右侧数组中。 @>
反过来。所以同时使用两者可以确保两个数组包含相同的元素:
a.code @> b.code AND a.code <@ b.code
尽管如此,如果一个数组包含重复项,它也会被接受。所以 [42,42]
将与 [42]
相同。如果你也想避免这种情况,你也应该检查数组长度
AND jsonb_array_length(a.code) = jsonb_array_length(b.code)
此外,您可以检查两个值是否都是 NULL
。这种情况要单独检查:
a.code IS NULL and b.code IS NULL
使用 COALESCE
函数的更短形式:
COALESCE(a.code, b.code) IS NULL
因此整个查询可能如下所示:
SELECT
*
FROM a
FULL OUTER JOIN b
ON a.id = b.id AND a.name = b.name
AND (
COALESCE(a.code, b.code) IS NULL -- both null
OR (a.code @> b.code AND a.code <@ b.code
AND jsonb_array_length(a.code) = jsonb_array_length(b.code) -- avoid accepting duplicates
)
)
之后,您可以过滤 WHERE
子句中的 NULL
值
我有 2 tables a 和 b
Table一个
id | name | code
VARCHAR VARCHAR jsonb
1 xyz [14, 15, 16 ]
2 abc [null]
3 def [null]
Tableb
id | name | code
1 xyz [16, 15, 14 ]
2 abc [null]
我想找出代码与相同 ID 和名称不匹配的地方。我对 b 中的代码列进行排序 b/c 我知道它相同但排序不同
SELECT a.id,
a.name,
a.code,
c.id,
c.name,
c.code
FROM a
FULL OUTER JOIN ( SELECT id,
name,
jsonb_agg(code ORDER BY code) AS code
FROM (
SELECT id,
name,
jsonb_array_elements(code) AS code
FROM b
GROUP BY id,
name,
jsonb_array_elements(code)
) t
GROUP BY id,
name
) c
ON a.id = c.id
AND a.name = c.name
AND COALESCE (a.code, '[]'::jsonb) = COALESCE (c.code, '[]'::jsonb)
WHERE (a.id IS NULL OR c.id IS NULL)
我在这种情况下的回答应该只有 return id = 3 b/c 它不在 b table 但我的查询也是 returning id = 2 b/c 我在内部子查询中没有很好地处理 null 情况 我如何处理内部子查询中的空用例?
<@
运算符检查左侧数组的所有元素是否都出现在右侧数组中。 @>
反过来。所以同时使用两者可以确保两个数组包含相同的元素:
a.code @> b.code AND a.code <@ b.code
尽管如此,如果一个数组包含重复项,它也会被接受。所以 [42,42]
将与 [42]
相同。如果你也想避免这种情况,你也应该检查数组长度
AND jsonb_array_length(a.code) = jsonb_array_length(b.code)
此外,您可以检查两个值是否都是 NULL
。这种情况要单独检查:
a.code IS NULL and b.code IS NULL
使用 COALESCE
函数的更短形式:
COALESCE(a.code, b.code) IS NULL
因此整个查询可能如下所示:
SELECT
*
FROM a
FULL OUTER JOIN b
ON a.id = b.id AND a.name = b.name
AND (
COALESCE(a.code, b.code) IS NULL -- both null
OR (a.code @> b.code AND a.code <@ b.code
AND jsonb_array_length(a.code) = jsonb_array_length(b.code) -- avoid accepting duplicates
)
)
之后,您可以过滤 WHERE
子句中的 NULL
值