在postgresql中的array_agg中将空数组设置为默认值

时间:2017-07-07 05:58:09

标签: postgresql

我有一个观点:

CREATE OR REPLACE VIEW microservice_view AS
  SELECT
    m.id :: BIGINT,
    m.name,
    m.sending_message_rate :: BIGINT,
    m.max_message_size :: BIGINT,
    m.prefetch_count :: BIGINT,
    (SELECT COALESCE(json_agg(DISTINCT node_id), '[]')
     FROM public.microservice_node
     WHERE microservice_id = m.id) AS nodes,

    (SELECT array_agg(DISTINCT json_build_object('id', transport_id :: INT,
                                                 'is_available', (credentials ->> 'is_available') :: BOOLEAN,
                                                 'username', credentials ->> 'username',
                                                 'password', credentials ->> 'password',
                                                 'default', (default_transport) :: BOOLEAN) :: JSONB
    )
     FROM transport_microservice
     WHERE microservice_id = m.id) AS transports
  FROM public.microservice m
  GROUP BY m.id
  ORDER BY m.id ASC;

有时传输为空。如何将空数组设置为array_agg的默认值?该字段应为空数组或包含数据的数组。在某些情况下,我使用array_length函数来过滤数据。

1 个答案:

答案 0 :(得分:2)

首先,我不会将array_agg与JSON混合(注意双引号转义;我也使用select array( .. subquery ..)技巧来获取数组,它在某种程度上是相当于您的array_agg(..)):

test=# select array(select '{"zz": 1}'::jsonb);
      array
-----------------
 {"{\"zz\": 1}"}

- 在这里你将获得JSONB的ARRAY,而你真正需要的是单个JSONB值,其中包含一个嵌入式数组:

test=# select pg_typeof(array(select '{"zz": 1}'::jsonb));
 pg_typeof
-----------
 jsonb[]
(1 row)


test=# select pg_typeof('[{"zz": 1}]'::jsonb);
 pg_typeof
-----------
 jsonb
(1 row)

要获取单个jsonb值(内置JSON数组),请使用jsonb_agg(..)函数。

要像往常一样默认替换NULL值,您可以使用标准函数coalesce(..)

test=# select coalesce(null::jsonb, '[]'::jsonb);
 coalesce
----------
 []
(1 row)

最后,正如我从其他评论中看到的那样,您需要获得jsonb的数组长度 - 有为此目的设计的函数json_array_length(..)jsonb_array_length(..),请参阅{{3 }}