简体   繁体   中英

sql query / getting latest entry based on two different conditions

this is my table structure:

[id] [senderid] [recipientid] [message] [datetime]

i want to get latest entry (based on datetime) for each conversation (for certain user), result should be (for own userid 1):

435 | 1 | 67 | how are u? | timestampnow

next result (after response):

436 | 67 | 1 | fine thanks | timestamplater

confused how to do query / join correctly. i tried somethink like:

SELECT * FROM messages MSG

INNER JOIN 
(SELECT MAX(id) MAXDATE,recipientid,senderid 
 FROM messages
 GROUP BY recipientid,senderid) MSG2

ON MSG.recipientid = MSG2.recipientid
AND MSG.id = MAXDATE 

Firts build a query with the conditions:

SELECT recipientid, MAX(date) mdate
FROM yourTable
GROUP BY recipientid

The use it as a subquery:

SELECT a.[id], a.[senderid], a.[recipientid], a.[message], a.[datetime]
FROM yourTable a
    INNER JOIN (SELECT recipientid, MAX(date) mdate
                FROM yourTable
                GROUP BY recipientid) b ON b.recipientid = a.recipientid
                                        AND a.datetime = b.mdate;

You don't need the sub select there

It might be as simple as that:

SELECT id, senderid, recipientid, message, MAX(datetime) as datetime
FROM yourTable
GROUP BY recipientid;
select m.*
from (
    select max(id) as id from (
        select max(id) as id, recipientid as user_id
        from messages
        where senderid = ?
        group by recipientid
        union all
        select max(id) as id, senderid as user_id
        from messages 
        where recipientid = ?
        group by senderid
    ) sub
    group by user_id
) sub
join messages m using(id)

The innermost subquery will return up to two id s per conversation (the id from last sent message and the id from last received message). The outer subquery will grab the highest of the two id s. Then the result is joined with the messages table to return the corresponding rows.

(Replace ? with the given user ID)

A shorter way could be:

select m.*
from (
    select max(id) as id
    from messages
    where ? in (senderid, recipientid)
    group by case when senderid = ? then recipientid else senderid end
) sub
join messages m using(id)

But that one might be slower.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM