为子查询优化 Postgresql 查询
Posted
技术标签:
【中文标题】为子查询优化 Postgresql 查询【英文标题】:Optimizing Postgresql Query for a Subquery 【发布时间】:2020-03-18 09:57:56 【问题描述】:我对 postgres 很陌生,这可能是一个新手问题。如何改进此查询?
三个表,campaigns
1-->M threads
1-->M messages
。我有活动 ID,并且我希望所有线程及其全部个体 opens
、clicks
和 replies
计数所有相关消息,其中 opens
和 clicks
在名为 extra
的 JSONB 字段中messages
和回复是具有 "direction"='received'
列的 messages
。
select "threads".*,
count("messages"."extra"->'opens') as opens,
count("messages"."extra"->'clicks') as clicks,
(
select count("messages"."id")
from "messages"
where "messages"."thread_id" = "threads"."id"
and "messages"."direction"='received'
) as replies
from "threads"
inner join "messages"
on "messages"."thread_id" = "threads"."id"
where "threads"."campaign_id"
in ('campaign_uuid')
group by "threads"."id"
【问题讨论】:
【参考方案1】:我认为你可以做一个条件计数:
select
t.id,
sum(jsonb_array_length(m.extra->'opens')) as opens,
sum(jsonb_array_length(m.extra->'clicks')) as clicks,
count(*) filter(where m.direction='received') as replies
from threads t
inner join messages m on m.thread_id = t.id
where t.campaign_id = 'campaign_uuid'
group by t.id
注意事项:
如果打开和点击都是jsonb数组,可以使用jsonb_array_length()
来计算它们的长度
threads.id
;如果您想要更多来自threads
的列,那么您应该在select
和group by
子句中添加它们。
除非确实需要,否则不要在标识符周围使用双引号(在您的查询中似乎不是这种情况)
表别名使查询更易读写
【讨论】:
感谢您的详细解释。我刚刚发现我的查询是错误的。clicks
和 opens
是数组。即使数组中有多个项目,count(m.extra->'opens') 也会计数为 1。如何获得总计数?认为我需要 SUM。
@Rocky 。 . .这回答了您最初提出的问题。如果你有不同的问题,你应该提出一个新的问题。我还建议您包括示例数据和所需的结果。
@Rocky:您可以使用jsonb_array_length()
来计算数组中的项目数。
我现在有了所有的答案。谢谢你的帮助(y)以上是关于为子查询优化 Postgresql 查询的主要内容,如果未能解决你的问题,请参考以下文章