MySQL选择发件人和收件人之间的最后对话消息

时间:2019-03-08 16:36:35

标签: mysql join subquery

我想查询一个表,以通过发件人ID或收件人ID获得发件人和收件人组之间的最后对话

我有下表

CREATE TABLE `messages` ( 
`message_id` Int( 11 ) AUTO_INCREMENT NOT NULL,
`author_id` Int( 11 ) NOT NULL,
`recipient_id` Int( 11 ) NOT NULL DEFAULT 0,
`message` Text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`date_created` Timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`date_updated` Timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`recipient_read` Int( 11 ) NOT NULL DEFAULT 0,
`attachment` VarChar( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
PRIMARY KEY ( `message_id` ),
CONSTRAINT `message_id` UNIQUE( `message_id` ) )
CHARACTER SET = utf8
COLLATE = utf8_general_ci
ENGINE = InnoDB;

样本数据:

+------------+-----------+--------------+---------------------------+---------------------+
| message_id | author_id | recipient_id |          message          |    date_created     |
+------------+-----------+--------------+---------------------------+---------------------+
|          1 |         1 |          101 | Hey buddy, what's up!     | 2019-03-08 11:11:07 |
|          2 |         1 |          101 | Hope all is well? :)      | 2019-03-08 11:11:30 |
|          3 |       101 |            1 | Yes, all good thanks      | 2019-03-08 11:25:04 |
|          4 |       101 |            1 | Super busy right now..    | 2019-03-08 11:25:16 |
|          5 |         1 |          101 | Same old stuff everyday.  | 2019-03-08 11:26:45 |
|          6 |         1 |          101 | Yea I guess so! but lis.. | 2019-03-08 11:27:26 |
|          7 |         1 |          100 | Hey man! hit me up, i've  | 2019-03-08 15:43:27 |
|          8 |         5 |          101 | Hola! come sta            | 2019-03-08 15:48:13 |
|         10 |         1 |           99 | Niky nejez sam            | 2019-03-08 16:06:18 |
|         11 |       101 |            1 | Last message!             | 2019-03-08 17:18:44 |
+------------+-----------+--------------+---------------------------+---------------------+

我要查询的是特定用户ID的最后一条消息,结果应返回与其进行对话的所有用户为该用户发送或接收的最后一条消息。

例如,对用户ID 1的查询应返回以下内容:

+------------+-----------+--------------+--------------------------+---------------------+
| message_id | author_id | recipient_id |         message          |    date_created     |
+------------+-----------+--------------+--------------------------+---------------------+
|          7 |         1 |          100 | Hey man! hit me up, i've | 2019-03-08 15:43:27 |
|         10 |         1 |           99 | Niky nejez sam           | 2019-03-08 16:06:18 |
|         11 |       101 |            1 | Last message!            | 2019-03-08 17:18:44 |
+------------+-----------+--------------+--------------------------+---------------------+

我整天想尽办法解决这个问题,尝试各种子查询和分组方式,但没有成功。

任何人都可以向我指出正确的方向。

4 个答案:

答案 0 :(得分:1)

您可以尝试将子查询用于最大日期之前的卷积组耦合自动子

SELECT  m.* 
FROM  messages m
INNER JOIN  (
    SELECT IF(author_id <= recipient_id, CONCAT(author_id,'_', recipient_id) ,CONCAT(recipient_id,'_', author_id) ) COUPLE, 
    MAX(date_created) max_date 
    FROM  messages
    GROUP BY COUPLE 
) t ON IF(m.author_id <= m.recipient_id,
         CONCAT(m.author_id,'_', m.recipient_id),
         CONCAT(m.recipient_id,'_', m.author_id) )  = t.COUPLE 
AND t.max_date  = m.date_created

答案 1 :(得分:0)

未经测试,但我想这就是您期望的结果。

SELECT * FROM
 (SELECT * FROM messages WHERE (author_id = 1 OR recipient_id = 1) ORDER BY 
 date_updated DESC) 
ORDER BY message_id ASC LIMIT 3

答案 2 :(得分:0)

我认为您需要在每个UNION上分别使用GROUP BYSELECT来获得所需的author_id ,recipient_iddata_updated,然后在创建的子查询和INNER JOIN表之间使用messages来获取其他数据:

SELECT  message_id
       ,author_id
       ,recipient_id
       ,message
       ,data_created
       ,data_updated
FROM   messages M
INNER JOIN
    (SELECT DISTINCT 
            author_id
           ,recipient_id
           ,MAX(date_updated) AS data_updated
    FROM    messages
    GROUP BY author_id
            ,recipient_id
    WHERE author_id = 'YOUR_USER_ID'
    UNION
    SELECT DISTINCT 
            author_id
           ,recipient_id
           ,MAX(date_updated) AS data_updated
    FROM    messages
    GROUP BY author_id
            ,recipient_id
    WHERE recipient_id = 'YOUR_USER_ID') A
ON  M.author_id = A.author_id 
AND M.recipient_id = A.recipient_id
AND M.data_updated = A.data_updated

答案 3 :(得分:0)

尝试一下:

    SELECT * FROM messages A LEFT JOIN
    (SELECT author_id,recipient_id,MAX(date_created) AS "DC" 
    FROM messages 
    GROUP BY author_id,recipient_id) B 
    ON A.author_id=B.author_id 
    AND A.recipient_id=B.recipient_id 
    AND A.date_created=B.DC 
    LEFT JOIN
    (SELECT author_id,recipient_id,MAX(date_updated) AS "DU" 
    FROM messages 
    GROUP BY author_id,recipient_id) C 
    ON A.author_id=C.author_id 
    AND A.recipient_id=C.recipient_id 
    AND A.date_updated=C.DU;

我有意在开头键入SELECT * FROM,因此它将显示表messages A和子查询B和C(基本上都是messages表)的所有列。这将允许您自定义表和/或子查询中的哪一列。希望这会有所帮助