我想检索给定父母的所有孩子。有三种情况需要区分:
让孩子们很容易:
select json_agg(child)
from child
where child.parent_id = :parent_id
json_agg
的一个问题是,当没有行时,它总是返回null
。因此,以下内容将返回值为null
而不是0
行的一行:
select json_agg(child)
from child
where false
这增加了区分这三种情况的复杂性。为了解决这个问题,我提出了以下建议:
with
parent as
(
select id
from parent
where id = :parent_id
),
result as
(
select coalesce(json_agg(child), '[]')
from child
inner join parent
on child.parent_id = parent.id
)
select result.*
from result
where exists(select * from parent)
这似乎有效,但它相当笨拙。我想知道是否有更好的解决方案。有什么想法吗?
更新
作为请求,这是我想要的:
[{...}, {...}, ...]
当有孩子的时候。[]
当没有孩子但父母存在时。no rows
。答案 0 :(得分:4)
在派生表中使用case
和聚合,例如:
select children
from (
select p.id, case when min(c.id) is null then '[]'::json else json_agg(c) end as children
from parent p
left join child c on c.parent_id = p.id
group by p.id
) s
where id = :parent_id
答案 1 :(得分:2)
这是聚合函数的正常行为,您只需要隐式GROUP BY <everything down to one row>
。那么,使用WHERE子句的聚合版本(&#39; HAVING&#39;)?
在那里,您可以检查NULL
和/或是否存在父母。
select COALESCE(json_agg(child), '[]') AS json_object
from child
where child.parent_id = :parent_id
HAVING json_agg(child) IS NOT NULL
OR EXISTS (SELECT * FROM parent WHERE id = :parent_id)
或者,有点干,但更详细...
SELECT
COALESCE(json_object, '[]'::json) AS json_object
FROM
(
select json_agg(child) AS json_object
from child
where child.parent_id = :parent_id
)
your_query
WHERE
json_object IS NOT NULL
OR EXISTS (SELECT * FROM parent WHERE id = :parent_id)