如何在Postgres中过滤JSON数组

时间:2017-06-21 15:12:28

标签: arrays json postgresql postgresql-9.5

我目前拥有此LEFT JOIN,这是更大选择

的一部分
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数组只包含非空值)

2 个答案:

答案 0 :(得分:2)

如果我理解了一切,那么你面临的问题就在于:

...
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 );

答案 1 :(得分:1)

array_remove函数现在将是您最好的选择: array_to_json(array_remove(array_agg(tags.*), null)) as tags