Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get highest ids in by an inner join and max id

I got two tables, conversations and messages, What I'd like to do is to make a inner join from conversations to messages.

Here is my query:

    SELECT 
    messages.msg,
    messages.`read`,
    conversations.userid,
    conversations.contactid

    FROM conversations 
        INNER JOIN messages ON 
        conversations.id = messages.convId
    WHERE conversations.id IN(443,444)

Now everything works as it should, but a last thing is that in the inner join where i use

conversations.id = messages.convId

I would like to get the highest ids only, like:

 AND MAX(messages.id)

But that doesn't work

EDIT: I tried once to use:

LEFT JOIN messages 
    ON conversations.id = messages.convId 
        AND messages.id = MAX(messages.id) 

But i got an error saying: Invalid use of group function.

like image 617
Kilise Avatar asked May 26 '13 15:05

Kilise


2 Answers

EDIT

This will work!

SELECT conversations.*, m1.* 
FROM conversations 
LEFT JOIN messages m1
    ON conversations.id = m1.cid 
    AND m1.id = (
            SELECT MAX(m2.id) 
            FROM messages m2 
            WHERE m2.cid = conversations.id
        )
like image 150
Phil Cross Avatar answered Sep 18 '22 13:09

Phil Cross


You are looking for the maximum value in a group. MySQL does not have any really obvious way to do this (lots of ways with a bit of trickery).

But, you are only looking for two groups. As such, you can just look for the limit in each group and combine them using union all:

SELECT m.msg, m.`read`, c.userid,
       c.contactid
FROM conversations c inner join
     ((select m.*
       from messages m
       where m.convid = 443
       order by m.id desc
       limit 1
      ) union all
      (select m.*
       from messages m
       where m.convid = 444
       order by m.id desc
       limit 1
      )
     ) m
     ON c.id = m.convId;

If you have indexes on messages(convid, id) and conversations(id), then this should be quite fast.

You can also do this using a more standard approach:

SELECT m.msg, m.`read`, c.userid,
       c.contactid
FROM conversations c inner join
     messages m
     ON c.id = m.convId
where c.convId in (443, 444) and
      m.id = (select max(id) from messages m2 where m2.convId = c.convId)
like image 30
Gordon Linoff Avatar answered Sep 18 '22 13:09

Gordon Linoff