Оптимизация Postgresql запроса для подзапроса - PullRequest
0 голосов
/ 18 марта 2020

Я довольно новичок в postgres, и это, вероятно, вопрос новичка. Как я могу улучшить этот запрос?

Три таблицы, campaigns 1 -> M threads 1 -> M messages. У меня есть идентификатор кампании, и я хочу, чтобы все потоки имели общее количество opens, clicks и replies всех связанных сообщений, где opens и clicks находятся в поле JSONB с именем extra в messages и ответы messages, которые имеют столбец "direction"='received'.

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 Ответ

1 голос
/ 18 марта 2020

I думаю , что вы можете просто выполнить условный подсчет:

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() для вычисления их длины

  • , которые вам нужно перечислить в предложении group by всех неагрегированных столбцов из предложения select - так что select * и grup by не go вместе хорошо; Я изменил запрос, чтобы выбрать только threads.id; если вам нужно больше столбцов из threads, то вы должны добавить их в оба предложения select и group by.

  • не используйте двойные кавычки вокруг идентификаторов, если они действительно не нужны (что не похоже на ваш запрос)

  • псевдонимы таблиц облегчают чтение и запись запроса

...