【问题标题】:MySQL select last converstion message between sender and recipientsMySQL选择发件人和收件人之间的最后一个转换消息
【发布时间】:2019-03-08 16:36:34
【问题描述】:

我希望通过发件人 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 |作者_id |收件人 ID |留言 |日期创建 |
+------------+------------+--------------+--------- ------------------+----------+
| 1 | 1 | 101 |嘿伙计,怎么了! | 2019-03-08 11:11:07 |
| 2 | 1 | 101 |希望一切安好? :) | 2019-03-08 11:11:30 |
| 3 | 101 | 1 |是的,很好,谢谢 | 2019-03-08 11:25:04 |
| 4 | 101 | 1 |现在超级忙.. | 2019-03-08 11:25:16 |
| 5 | 1 | 101 |每天都一样的旧东西。 | 2019-03-08 11:26:45 |
| 6 | 1 | 101 |是的,我想是的!但李.. | 2019-03-08 11:27:26 |
| 7 | 1 | 100 |嗨,老兄!打我,我已经 | 2019-03-08 15:43:27 |
| 8 | 5 | 101 |你好!来吧 | 2019-03-08 15:48:13 |
| 10 | 1 | 99 | Niky nejez sam | 2019-03-08 16:06:18 |
| 11 | 101 | 1 |最后一条消息! | 2019-03-08 17:18:44 |
+------------+------------+--------------+--------- ------------------+------------------------+

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

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

+------------+------------+--------------+------ -----------------+---------+
| message_id |作者_id |收件人 ID |留言 |日期创建 |
+------------+------------+--------------+--------- -----------------+----------+
| 7 | 1 | 100 |嗨,老兄!打我,我已经 | 2019-03-08 15:43:27 |
| 10 | 1 | 99 | Niky nejez sam | 2019-03-08 16:06:18 |
| 11 | 101 | 1 |最后一条消息! | 2019-03-08 17:18:44 |
+------------+------------+--------------+--------- -----------------+------------------+

我整天都在绞尽脑汁想弄清楚这一点,并尝试了各种子查询和分组,但没有任何成功。

谁能指点我正确的方向。

【问题讨论】:

  • 看看你是否可以在不包括一张图片的情况下提出同样的问题。
  • 另外,recipient_read 存储什么样的值?
  • @Strawberry 感谢您的提示。我会用正确的格式更新问题

标签: mysql join subquery


【解决方案1】:

您可以尝试使用子查询来查询最大日期的 convdrsation 组的耦合自动

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

【讨论】:

  • 非常感谢@scaisEdge,这个查询返回了我所期望的。不过,查询中有一些错字。 COUPLE、MAX 之间的逗号并将 mauthor_id 更改为 m.author_id
  • 在做了一些测试@scaisEdge 之后,我注意到这个查询只有在没有 2 条消息同时发布的情况下才有效。如果作者和收件人在完全相同的 date_time 发布消息,则返回重复行
【解决方案2】:

未经测试,但我想这是您所需要的,符合您的预期结果。

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

【讨论】:

  • 是的,不应该有任何限制,应该选择所有对话
【解决方案3】:

我认为您需要在每个 SELECT 上使用 UNIONGROUP BY 来获取您正在寻找的 author_id ,recipient_iddata_updated,然后在创建的子查询和 @ 之间添加 INNER JOIN 987654327@表获取其他数据:

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

【讨论】:

    【解决方案4】:

    试试这个:

        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 表)。这将允许您自定义表和/或子查询中的哪一列。希望这会有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      相关资源
      最近更新 更多