2017-06-21 49 views
0

有这个LEFT JOIN这是一个更大的一部分选择我目前如何过滤JSON数组中的Postgres

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或在阵列上使用json_strip_nulls或有FILTER,但我没有达到正确的结果(JSON数组只包含非空值)

回答

1

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

... 
array_to_json(array_agg(tags.*)) as tags 
... 

也许你在一个错误的方式使用FILTER,但这并工作eliminta 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); 
+0

谢谢,过滤器真的有效。我敢打赌,我写了完全相同的代码,但显然不是:) –

+0

只要它的工作现在重要,休息是历史:D –