图片:两个表,案例和case_messages。案例可以包含任意数量的消息或者没有消息。其中一条消息可能是案例中的最终答案。我现在想要返回一个包含bool列的案例列表,告诉我是否有最终答案。如果对于一个案例根本没有消息,则查询应该返回“false”。仅当case_messages中至少有一条相关消息isfinalanswer = true时,查询才返回true。我设法使用coalesce和子查询来处理这个问题,但感觉非常难看:
SELECT cases.id, cases.title,
COALESCE((SELECT isfinalanswer FROM case_messages WHERE caseid = cases.id ORDER BY isfinalanswer DESC LIMIT 1), false) AS hasfinalanswer,
FROM cases;
我该如何改进?
答案 0 :(得分:2)
我建议使用exists
:
SELECT c.id, c.title,
(exists (SELECT 1 FROM case_messages cm WHERE cm.caseid = c.id and isfinalanswer = true)
) as hasfinalanswer
FROM cases c;
我不知道你是否会认为这不那么难看。
我应该为性能添加(在问题中没有提到),你需要case_messages(caseid, isfinalanswer)
上的索引。有了这样的索引,这可能是最有效的解决方案。
答案 1 :(得分:2)
相关子查询(选择列表上的查询)可能会对性能产生不利影响。执行left join
和distinct on
select distinct on (c.id)
c.id, c.title,
coalesce(cm.isfinalanswer, false) as hasfinalanswer
from
cases c
left join
case_messages cm on cm.caseid = c.id
order by 1, 3 desc
在这种情况下,coalesce
可以替换为is true
cm.isfinalanswer is true as hasfinalanswer
修改:为避免order by
所需的distinct on
费用进行预先汇总
select id, title, coalesce(isfinalanswer, false) as hasfinalanswer
from
cases c
left join (
select caseid as id, bool_or(isfinalanswer) as isfinalanswer
from case_messages
group by 1
) cm using (id)