Sql 有没有更好的方法来区分无子项或无效的父项标识符?
我要检索给定父对象的所有子对象。有三种情况需要区分:Sql 有没有更好的方法来区分无子项或无效的父项标识符?,sql,postgresql,Sql,Postgresql,我要检索给定父对象的所有子对象。有三种情况需要区分: 如果存在子项,则以JSON数组返回它们 没有子级但父级存在,返回空JSON数组 父级不存在,请不要返回任何内容 得到孩子很容易: select json_agg(child) from child where child.parent_id = :parent_id json_agg的一个问题是,当没有行时,它总是返回null。因此,下面将返回一行值null,而不是0行: select json_agg(child) from
- 如果存在子项,则以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)
这似乎有效,但相当笨拙。我想知道是否有更好的解决办法。有什么想法吗
更新
根据要求,这是我想要的:
当有子对象时[{…},{…},…]
当没有子项但父项存在时[]
- 父级不存在时,无行
分组依据
。那么,使用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)
将
大小写
与派生表中的聚合一起使用,例如:
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
有json_agg(child)不是空的
?我需要区分这3种情况。添加使json_agg(child)不为空
将不允许我区分父项存在但当前没有子项
情况,如果我是对的话?请回答您的问题,并根据该数据添加一些和预期输出。求你了,@a_horse_和_no_name我添加了预期的输出。这些信息够了吗?你能解释一下你为什么要做min(c.id)
?它只检查是否有子项(注意,他也是按parent.id
分组的,不能检查c.id
而周围没有聚合…(尽管它似乎与COALESCE(json_agg(c),“[]”:json)具有相同的效果)
)@KevinDeGrote规划师将有效地使用“类似宏的扩展”将条件传播到内部查询。(假设内部查询是一个视图,因为子查询也被称为内联视图,规划器可以很容易地理解为处理视图,所以…)如果没有这样的逻辑,SQL将像驴子球一样。(更严重的是,SQL是一种“声明性”语言,而不是大多数人都熟悉的“命令式”语言。这意味着,乐观主义者/规划者/任何你喜欢的术语都可以选择它认为合适的任何方式来解决你所声明的问题。这给了它很大的“为你聪明”的空间。)@KevinDeGrote-当有疑问时,对两个查询使用解释分析
,计划将是相同的。如果min(c)为空
似乎有问题,可以使用count(c)=0
这可能更直观。@MatBailie-谢谢你的宝贵评论。有趣的方法。我们只需要重复一下json\u agg(child)
。这基本上是我最初的问题:)。@KevinDeGrote-我个人认为克林的答案比我的好。左连接的成本与存在的成本相同,它对案例更加严格,而不是COALESCE()
,只有:parent\u id
参数一次…这很“笨拙”,但在我看来不是一个黑客。COUNT(c.id)>0会让你感觉更好吗?有道理count(c.id)=0感觉确实更正确,但我想我在这里太迂腐了。