Messages table in MySQL, getting last message for each thread

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

I am trying to get the last message from each conversation, the only problem is I am not using a conversations table.

I am using one messages table, my table columns looks like this:

id  from_id     to_id   text    isread  isseen  created_at  updated_at 

Right now I am able to retrieve conversations like this:

$messages = Message::select('*')->                 from(DB::raw("(select * from `messages` where `to_id` = ".Auth::id()." order by `created_at` desc) as sub"))->                 groupBy('from_id')->orderBy('created_at', 'desc')->                 paginate(7);

The only downside to this is I am not retrieving the last message for each conversation, I am retrieving the last message received.

How can I retrieve the last message of each conversation?

Example Retrieve user63 conversations and last message for each conversation:

id  from_id     to_id   text    isread  isseen  created_at  updated_at  23  224         63      a        0         0    2015-03-28 22:23:54     2015-03-28 22:23:54 20  63          225     b        0        0     2015-03-28 22:23:06     2015-03-28 22:23:06 16  225         63      hi       0        1     2015-03-28 22:21:32     2015-03-28 22:21:32

I thought of an idea, not sure though:

$messages = Message::select('*')->             from(DB::raw(" ( (select *, to_id as theuser from `messages` where `to_id` = ".Auth::id()." order by `created_at` desc) union (select *, from_id as theuser from `messages` where `from_id` = ".Auth::id()." order by `created_at` desc) group by theuser ) as sub"))->             groupBy('from_id')->orderBy('created_at', 'desc')->             paginate(7);

回答1:

This must works too: The difference in this approach is a self join with a little help from max() function like this:

SELECT from_id, MAX(created_at) AS last FROM messages GROUP BY from_id

So:

$pagedMessages = Message::select('*')->   from(     DB::raw("         messages AS m          JOIN (             SELECT from_id, MAX(created_at) AS lm FROM messages GROUP BY from_id         ) AS lm          ON lm.from_id = m.from_id AND lm.created_at = m.created_at      "))-> paginate(7);


回答2:

I found a solution myself, thanks everyone! :)

$messages = Message::select('*')-> from(DB::raw("     (        SELECT *,`from_id` as `theuser`       FROM `messages` WHERE `to_id` = 63       union       SELECT *,`to_id` as `theuser`       FROM `messages` WHERE `from_id` = 63       order by `created_at` desc     ) as `sub`"))->groupBy('theuser')->                    orderBy('created_at', 'desc')->                    paginate(7);


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!