如何在 Postgres 中过滤 JSON 数组
How to filter JSON array in Postgres
我目前有这个 LEFT JOIN
,它是更大 select
的一部分
LEFT JOIN (
SELECT
tags_components.component_id,
array_to_json(array_agg(tags.*)) as tags
FROM tags_components
LEFT JOIN tags ON tags.id = tags_components.tag_id AND tags_components.component_name = 'contact'
GROUP BY tags_components.component_id
) AS tags ON tags.component_id = contact.id
如果组件已分配所有标签,这将按预期工作。但是 tags
数组的大小始终为 COUNT(tags.*)
,因此对于没有任何标签的组件,将填充 null
。有没有办法过滤掉那些空值?我尝试了不同的方法,例如在数组上使用 json_strip_nulls
或使用 FILTER
但我没有获得正确的结果(JSON 数组仅包含非空值)
如果我理解正确,那么你遇到的问题是:
...
array_to_json(array_agg(tags.*)) as tags
...
也许您以错误的方式使用了 FILTER
,但这确实可以消除 NULL
结果,例如:
SELECT array_to_json(
-- FILTER is applied to this specific 'array_agg'
array_agg( t.* ) FILTER ( WHERE t.tag IS NOT NULL )
)
FROM ( VALUES
( 'a1' ),
( 'b1' ),
( null ),
( 'c1' ),
( null ),
( 'd1' )
) t( tag );
-- Resolves to:
array_to_json
-------------------------------------------------------
[{"tag":"a1"},{"tag":"b1"},{"tag":"c1"},{"tag":"d1"}]
(1 row)
或者您可以使用 jsonb_agg
(在 Postgres Aggregate Functions 阅读更多内容)而不是 array_to_json + array_agg
来提供相同的结果,例如:
SELECT jsonb_agg( t.* ) FILTER ( WHERE t.tag IS NOT NULL )
FROM ( VALUES
( 'a1' ),
( 'b1' ),
( null ),
( 'c1' ),
( null ),
( 'd1' )
) t( tag );
array_remove 函数现在将是您最好的选择:
array_to_json(array_remove(array_agg(tags.*), null)) as tags
我目前有这个 LEFT JOIN
,它是更大 select
LEFT JOIN (
SELECT
tags_components.component_id,
array_to_json(array_agg(tags.*)) as tags
FROM tags_components
LEFT JOIN tags ON tags.id = tags_components.tag_id AND tags_components.component_name = 'contact'
GROUP BY tags_components.component_id
) AS tags ON tags.component_id = contact.id
如果组件已分配所有标签,这将按预期工作。但是 tags
数组的大小始终为 COUNT(tags.*)
,因此对于没有任何标签的组件,将填充 null
。有没有办法过滤掉那些空值?我尝试了不同的方法,例如在数组上使用 json_strip_nulls
或使用 FILTER
但我没有获得正确的结果(JSON 数组仅包含非空值)
如果我理解正确,那么你遇到的问题是:
...
array_to_json(array_agg(tags.*)) as tags
...
也许您以错误的方式使用了 FILTER
,但这确实可以消除 NULL
结果,例如:
SELECT array_to_json(
-- FILTER is applied to this specific 'array_agg'
array_agg( t.* ) FILTER ( WHERE t.tag IS NOT NULL )
)
FROM ( VALUES
( 'a1' ),
( 'b1' ),
( null ),
( 'c1' ),
( null ),
( 'd1' )
) t( tag );
-- Resolves to:
array_to_json
-------------------------------------------------------
[{"tag":"a1"},{"tag":"b1"},{"tag":"c1"},{"tag":"d1"}]
(1 row)
或者您可以使用 jsonb_agg
(在 Postgres Aggregate Functions 阅读更多内容)而不是 array_to_json + array_agg
来提供相同的结果,例如:
SELECT jsonb_agg( t.* ) FILTER ( WHERE t.tag IS NOT NULL )
FROM ( VALUES
( 'a1' ),
( 'b1' ),
( null ),
( 'c1' ),
( null ),
( 'd1' )
) t( tag );
array_remove 函数现在将是您最好的选择:
array_to_json(array_remove(array_agg(tags.*), null)) as tags