【问题标题】:How to filter JSON array in Postgres如何在 Postgres 中过滤 JSON 数组
【发布时间】:2017-11-24 14:04:35
【问题描述】:

我目前有这个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_nullsFILTER,但我没有得到正确的结果(JSON 数组只包含非空值)

【问题讨论】:

    标签: arrays json postgresql postgresql-9.5


    【解决方案1】:

    如果我正确理解了所有内容,那么您面临的问题就是:

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

    【讨论】:

    • 谢谢,过滤器确实有效。我敢打赌我写了完全相同的代码,但显然不是:)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2014-07-05
      • 1970-01-01
      • 2017-09-15
      • 2018-08-22
      • 1970-01-01
      • 2022-01-15
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多