我有一个观点:
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函数来过滤数据。
答案 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 }}