Reputation: 23
I have a table of data as follows
id status conversation_id message_id date_created
1 1 1 72 2012-01-01 00:00:00
2 2 1 87 2012-03-03 00:00:00
3 2 2 95 2012-05-05 00:00:00
I want to get all the rows from the table in date_created
DESC order, but only one row per conversation_id
. So in the case of the example data above, I would want to get the rows with id
2 and 3.
Any advice is much appreciated.
Upvotes: 0
Views: 211
Reputation: 125204
Creation and inserts borrowed from @Incidently:
CREATE TABLE T
(id int, status int, conversation_id int, message_id int, date_created datetime);
insert into T (id, status, conversation_id, message_id, date_created)
values(1, 1, 1, 72, '2012-01-01 00:00:00');
insert into T (id, status, conversation_id, message_id, date_created)
values(2, 2, 1, 87, '2012-03-03 00:00:00');
insert into T (id, status, conversation_id, message_id, date_created)
values(3, 2 , 2 , 95 , '2012-05-05 00:00:00');
Supposing the id is the primary key then this solves the problem pointed by @Incidentally in @Joe's answer:
select T.*
from
T
inner join (
select conversation_id, max(id) as id
from T
group by conversation_id
) s on s.id = T.id
order by T.date_created desc, T.conversation_id
;
+------+--------+-----------------+------------+---------------------+
| id | status | conversation_id | message_id | date_created |
+------+--------+-----------------+------------+---------------------+
| 3 | 2 | 2 | 95 | 2012-05-05 00:00:00 |
| 2 | 2 | 1 | 87 | 2012-03-03 00:00:00 |
+------+--------+-----------------+------------+---------------------+
Upvotes: 0
Reputation: 4349
See SQL Fiddle
SELECT T.*
FROM T
WHERE NOT EXISTS (
SELECT *
FROM T AS _T
WHERE _T.conversation_id = T.conversation_id
AND (
_T.date_created > T.date_created
OR
_T.date_created = T.date_created AND _T.id > T.id)
)
ORDER BY T.date_created DESC
gets
ID STATUS CONVERSATION_ID MESSAGE_ID DATE_CREATED
3 2 2 95 May, 05 2012
2 2 1 87 March, 03 2012
Upvotes: 1
Reputation: 135729
SELECT t.id, t.status, t.conversation_id, t.message_id, t.date_created
FROM YourTable t
INNER JOIN (SELECT conversation_id, MAX(date_created) AS MaxDate
FROM YourTable
GROUP BY conversation_id) q
ON t.conversation_id = q.conversation_id
AND t.date_created = q.MaxDate
ORDER BY t.date_created DESC;
Upvotes: 2