Select the first result of each conversation

Asked

Viewed 121 times

2

How can I select the first line of each conversation from a specific user where the to_id = 1.

The big problem is when the first message exchanged from the conversation does not have the top_id = 1 and ends up listing the next message of the conversation that has the from_id = 1, when you shouldn’t have.

Here is the link to the SQLFIDDLE: http://www.sqlfiddle.com/#! 9/7a772b/4

In SQLFIDDLE you are listing the Test 1 and the Test 4 when you should be listing only the Test 1, why the conversation Test 4 begins in the Test 3 where there is no to_id = 1.

SQL

SELECT t1.*, m2.message, m2.from_id FROM
    (SELECT to_id,message, MIN(created_at) AS created_at FROM messages m
    WHERE to_id = 1
    GROUP BY to_id,message) AS t1
INNER JOIN messages m2 ON t1.created_at = m2.created_at

3 answers

1


Try this:

SELECT m1.to_id, m1.message, m1.created_at, m1.from_id
FROM messages m1
WHERE m1.to_id = 1
AND m1.created_at <= IFNULL(
                      (SELECT m2.created_at
                      FROM messages m2
                      WHERE (m2.from_id = m1.to_id AND m2.to_id = m1.from_id)
                      OR (m2.from_id = m1.from_id AND m2.to_id = m1.to_id)
                      LIMIT 1)
                    , NOW())
GROUP BY m1.to_id, m1.created_at
  • Dude, when a user sends two messages before the other user sends at least one, they end up not listing. Do you have any idea how to fix this?

  • http://www.sqlfiddle.com/#! 9/8c8e09/2 In this example you should continue listing "test 1" and "test 3", but list only "test 1"

  • I saw your edition and is returning the test 3 straight, but the problem is that is returning the test 4 also.

  • I added the IFNULL clause for when there is no reply and the OR after WHERE to filter when the user sends two or more messages in a row.

  • Show! Thank you very much!

1

I did it the way I thought was right, I tested it here and it worked perfectly.

SELECT 
  t1.* 
FROM
  (SELECT * FROM messages) t1 
  INNER JOIN messages t2 
    ON (t2.id = t1.from_id AND t2.from_id = t1.id)
WHERE t1.to_id = 1

0

The query is well planned, the problem is in the organization of it.

Your current query (Sqlfiddle) looks like this

SELECT t1.*, m2.message, m2.from_id FROM
    (SELECT to_id,message, MIN(created_at) AS created_at FROM messages m
    WHERE to_id = 1
    GROUP BY to_id,message) AS t1
INNER JOIN messages m2 ON t1.created_at = m2.created_at

You’re going through so much id how much message as a reference to the GROUP BY which ironically has no logic.

To work just remove message of GROUP BY, leaving your query like this

SELECT t1.*, m2.message, m2.from_id FROM
    (SELECT to_id,message, MIN(created_at) AS created_at FROM messages m
    WHERE to_id = 1
    GROUP BY to_id) AS t1
INNER JOIN messages m2 ON t1.created_at = m2.created_at

Sqlfiddle: http://www.sqlfiddle.com/#! 9/7a772b/10

  • It can’t be that way, because when the conversation between user 1 and 3 starts with "to_id = 1" it doesn’t list it. I made a small change in the table data to give you an idea: http://www.sqlfiddle.com/#! 9/154fa9/7

  • In this case you should list "Test 1" and "Test 3".

  • It was very confusing! In the thread you say you should list only Test 1, in case the query should pull the 2 converse, both Test 1 and Test 3? Even if that is so it is not logical to use group by in both. I’ll take a look at this other query

  • I said that in that example I should list only test 1

  • The general idea is to list the first message exchanged between user 1 and the others, where this first message has to_id = 1

  • The problem is that when someone starts sending a message to user 1, and then he responds, he can’t list this conversation because it didn’t start with user 1 receiving a message. This is the example I sent on SQLFIDDLE now last.

  • If I understand correctly, user X sends a message to user Y, and user X responds, this conversation cannot be displayed, but if user X does not respond, it should be listed, that for all users?

  • The idea is to list the first message of each conversation that the logged-in user did not start. It doesn’t matter if they responded or not

  • In the case of your example, if user X is logged in, you should not list the first message he sent to user Y. However, if user Y is logged in, you should list, because he received the message first.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.