I have the following table. I am actually designing a simple chat, so, we have the user_id (the person who sends the message) and user_id_to (the person who receives the message).
id | user_id | user_id_to | message | send_date |
---|---|---|---|---|
1 | 1 | 2 | test 1 | 01-2-2023 |
2 | 2 | 1 | test 2 | 02-2-2023 |
3 | 3 | 1 | test 3 | 03-2-2023 |
4 | 1 | 2 | test 4 | 05-3-2023 |
5 | 2 | 1 | test 5 | 08-3-2023 |
6 | 3 | 1 | test 6 | 10-3-2023 |
7 | 4 | 1 | test 7 | 11-3-2023 |
8 | 5 | 1 | test 8 | 13-3-2023 |
9 | 5 | 1 | test 9 | 15-3-2023 |
10 | 5 | 1 | test 10 | 20-3-2023 |
11 | 1 | 3 | test 11 | 22-3-2023 |
I want to be able to select the distinct user (grouped by user), and message, order by max send_date.
So, with the above data, the following should be the result.
id | user_id | user_id_to | message | send_date |
---|---|---|---|---|
11 | 1 | 3 | test 11 | 22-3-2023 |
10 | 5 | 1 | test 10 | 20-3-2023 |
7 | 4 | 1 | test 7 | 11-3-2023 |
5 | 2 | 1 | test 5 | 08-3-2023 |
I need to use Laravel Eloquent, because with that I can use with(‘user’, ‘user_to’) to select the users data together.
Answer provided by Karl Hill works, but it didn’t select the message column. How can I also select the message column?
Please help.
2
Answers
You can use Eloquent’s
groupBy
,orderBy
, andwith
methods. Convert thesend_date
to a date format that MySQL can understand. You can do this by addingsend_date
to your model’s$dates
property.Then, use the
DB::raw
function to select the maximumsend_date
for eachuser_id
. You can then group byuser_id
and order by the maximumsend_date
.This query will return the latest chat for each user, not the latest chat for each pair of users. If you want to get the latest chat for each pair of users, you should group by both
user_id
anduser_id_to
.First, let’s see this with a raw SQL query:
Here, we find the latest record by left joining
latest
tofollowup
based onuser_id
anduser_id_to
matching as well asfollowup
being later thanlatest
. In thewhere
clause we ensure that only thoselatest
records are selected that have nofollowup
matches, that is, they are indeed the latest.Now, let’s convert this into an Eloquent query: