有没有更好的方法来区分没有孩子或无效的父母身份?

问题描述 投票:3回答:2

我想为给定的父母检索所有孩子。有三种情况需要区分:

  • 有子节点,以JSON数组返回它们。
  • 没有子节点,但父节点存在,返回一个空的JSON数组。
  • 父母不存在,不返回任何东西。

让孩子们很容易:

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
sql postgresql
2个回答
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

2
投票

这是聚合函数的正常行为,你只需要一个隐含的GROUP BY <everything down to one row>。那么,使用WHERE子句的聚合版本('HAVING')?

在那里你可以检查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)
© www.soinside.com 2019 - 2024. All rights reserved.