Чтобы получить последнее сообщение для ваших разговоров, есть способы добиться этого, например, самостоятельное объединение или оконные функции (row_number (), rank () et c). Используя оконную функцию, вы можете написать свой запрос как
with cm as (
select *,
rank() over (partition by conversation_id order by created desc) as r
from conversation_message
)
select c.id,
c.title,
cm.body,
cm.created,
cm.r,
cu.display_name
from conversation as c
left join cm on c.id = cm.conversation_id and cm.r <= 1
left join chat_user cu on cu.id = cm.sender_id
DEMO
В приведенном выше запросе я использовал левые соединения, чтобы включить преобразования без сообщений, если вам нужно только разговоры, в которых есть сообщения, затем используют внутренние объединения. Если вам нужно более одного последнего сообщения для каждого изменения разговора cm.r <= @no
Чтобы получить список участников для каждого разговора, вы можете добавить новый CTE, например
with cm as (
select *,
rank() over (partition by conversation_id order by created desc) as r
from conversation_message
),
message_participants as (
select
m.conversation_id,
array_agg(u.display_name order by m.created desc) as participants
from chat_user as u
join conversation_message as m on u.id = m.sender_id
group by m.conversation_id
)
select c.id,
c.title,
cm.body,
cm.created,
cm.r,
cu.display_name,
cmp.participants
from conversation c
left join cm on c.id = cm.conversation_id and cm.r <= 1
left join chat_user cu on cu.id = cm.sender_id
left join message_participants cmp on c.id = cmp.conversation_id
DEMO
Улучшения
Добавьте user_id
в conversation
таблицу, чтобы определить, кто создал этот диалог.
Таблица conversation_participant
является избыточным, а вы можете извлечь список участников из conversation_message