Answer the question
In order to leave comments, you need to log in
MySQL - fetching conversations with the last 3 messages?
Good afternoon!
There are two tables:
--- dialogs
- id
- date_latest_message
--- dialog_messages
- id
- dialog_id
- message
- added_date
SELECT
D.dialog_id,
D.date_latest_message,
DM.message,
DM.added_date AS message_added_date
FROM (
SELECT
d.id AS dialog_id,
d.date_latest_message
FROM dialogs d
WHERE DATE(d.date_latest_message) BETWEEN '2020-10-01' AND '2021-10-08'
) D LEFT JOIN (
SELECT
dm.message,
dm.dialog_id,
dm.id,
dm.added_date
FROM dialog_messages dm
WHERE 1
ORDER BY dm.id DESC
LIMIT 3
) DM ON DM.dialog_id=D.dialog_id
WHERE 1
ORDER BY D.date_latest_message DESC
Answer the question
In order to leave comments, you need to log in
Option for MySQL below version 8:
select A.*
from
(
SELECT d.id AS dialog_id,
d.date_latest_message,
(select max(DM.added_date)
from dialog_messages dm3
where dm3.dialog_id = dm.dialog_id
) as datetime_latest_message,
Dm.Id as Dm_Id,
DM.message,
DM.added_date
FROM dialogs d
join dialog_messages dm on DM.dialog_id = D.dialog_id
WHERE (select count(*)
from dialog_messages dm2
where dm2.dialog_id = dm.dialog_id
and dm2.id > dm.id -- по идент. будет эффективнее работать, чем по дате-время, к тому же первичный ключ, как правило, проиндексирован, не требуется доп. индексов
) < 3 -- берем только те сообщения, которые позднее опубликованы чем текущее (3 вышестоящих)
and DATE(d.date_latest_message BETWEEN) '2020-10-01' AND '2021-10-08'
) A
order by A.datetime_latest_message desc, A.Dm_Id desc
select A.*
from
(
SELECT
d.id AS dialog_id,
d.date_latest_message,
(select max(DM.added_date)
from dialog_messages dm3
where dm3.dialog_id = dm.dialog_id
) as datetime_latest_message,
Dm.Id as Dm_Id,
DM.message,
DM.added_date AS message_added_date,
row_number() over (partition by d.id -- окно счетчика в пределах идент. диалога
order by DM.Id desc -- направление сортировки счетчика
) dm_rownum -- счетчик для отсечения порций
FROM dialogs d
join dialog_messages dm on DM.dialog_id = D.dialog_id
WHERE DATE(d.date_latest_message) BETWEEN '2020-10-01' AND '2021-10-08'
) A
where A.dm_rownum <= 3 -- отсекаем нужное число "локальных" отсчетов
ORDER BY A.datetime_latest_message DESC, A.Dm_Id DESC
Maybe it's easier to add a sign to the message that it is "in the last three"? Well, or in the plate next to store the identifiers of chats and recent messages? And when adding a new message, update the data? Then the query is simplified to disgrace + given that the update is much less frequent than the insert - everything will be much better with performance.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question