【问题标题】:SQL select last messageSQL 选择最后一条消息
【发布时间】:2018-10-28 21:39:20
【问题描述】:

我有一张桌子:

CREATE TABLE `tMessages` (
 `tMessages_id` bigint(20) NOT NULL AUTO_INCREMENT,
 `tUsers_sender_uid` bigint(20) NOT NULL,
 `tUsers_recipient_uid` bigint(20) NOT NULL,
 `tMessages_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `tMessages_text` varchar(2000) NOT NULL,
 PRIMARY KEY (`tMessages_id`),
 KEY `tUsers_sender_uid` (`tUsers_sender_uid`),
 KEY `tUsers_recipient_uid` (`tUsers_recipient_uid`),
 KEY `tUsers_uids` (`tUsers_sender_uid`,`tUsers_recipient_uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

我需要:

1) 选择两个用户之间的所有消息,我这样做了:

SELECT * FROM `tMessages` FORCE INDEX (tUsers_uids) WHERE tUsers_sender_uid = 1 AND tUsers_recipient_uid=2 OR tUsers_sender_uid=2 AND tUsers_recipient_uid = 1

-- 这是一种快速的方法吗?

2) 在 uid = 1 和其他用户之间的所有消息组中选择最后一条消息

-- 我该怎么做?

【问题讨论】:

  • This is fast method 不是问号,为什么后面要加问号?
  • @IONIX,你有关于这方面的更新吗?我们在这里努力为您提供帮助。

标签: sql optimization query-optimization


【解决方案1】:

这是第一部分...需要括号吗?

SELECT * FROM `tMessages`
WHERE (tUsers_sender_uid = 1 AND tUsers_recipient_uid=2)
 OR (tUsers_sender_uid=2 AND tUsers_recipient_uid = 1)

第二部分可能更具挑战性......但这应该会让你走上正轨。

select coalesce(r.recipient, s.sender) OtherParty, 
    case when coalesce(r.`tMessages_id`,s.`tMessages_id`) > coalesce(s.`tMessages_id`,r.`tMessages_id`)
        then coalesce(r.`tMessages_id`,s.`tMessages_id`)
        else coalesce(s.`tMessages_id`,r.`tMessages_id`)
    end messageid
from
    (select `tUsers_recipient_uid` recipient, max(`tMessages_id`) `tMessages_id` 
    from `tMessages`
    where `tUsers_sender_uid` = 1
    group by `tUsers_recipient_uid`) r
full outer join (
    select `tUsers_sender_uid` sender, max(`tMessages_id`) `tMessages_id`
    from `tMessages`
    where `tUsers_recipient_uid`= 1
    group by `tUsers_sender_uid`) s
on r.recipient = s.sender

【讨论】:

    【解决方案2】:
    SELECT m.*  
      FROM tMessages m
      WHERE (tUsers_sender_uid = 1 AND tUsers_recipient_uid=2 OR tUsers_sender_uid=2 AND tUsers_recipient_uid = 1)
        and tMessages_timestamp = (select max(tMessages_timestamp) 
                                     from tMessages 
                                     WHERE (tUsers_sender_uid = 1 AND tUsers_recipient_uid=2 OR tUsers_sender_uid=2 AND tUsers_recipient_uid = 1));
    

    【讨论】:

    • 在两个用户之间)。我需要tUsers_sender_uid = 1 或tUsers_recipient_uid = 1 的所有最后消息
    【解决方案3】:

    试试这个

    select top(1)* from tMessages WHERE (tUsers_sender_uid = 1
    AND tUsers_recipient_uid=2) OR (tUsers_sender_uid=2 AND 
    tUsers_recipient_uid = 1) order by tMessages_timestamp desc
    

    【讨论】:

      【解决方案4】:

      此消息将返回任意 2 个用户之间的所有最后消息:

      SELECT m.*  
        FROM tMessages m
          where tMessages_timestamp = (select max(tMessages_timestamp) 
                                         from tMessages 
                                         WHERE (tUsers_sender_uid = m.tUsers_sender_uid    AND tUsers_recipient_uid = m.tUsers_recipient_uid OR 
                                                tUsers_sender_uid = m.tUsers_recipient_uid AND tUsers_recipient_uid = m.tUsers_sender_uid));
      

      【讨论】:

        【解决方案5】:

        这将返回某个用户(即 1)和任何其他用户之间的所有最后一条消息:

        SELECT m.*  
          FROM tMessages m
            where m.tMessages_timestamp = (select max(tMessages_timestamp) 
                                           from tMessages 
                                           WHERE (tUsers_sender_uid = 1                      AND tUsers_recipient_uid = m.tUsers_recipient_uid OR 
                                                  tUsers_sender_uid = m.tUsers_recipient_uid AND tUsers_recipient_uid = 1))
              and (m.tUsers_sender_uid = 1 or m.tUsers_recipient_uid = 1);
        

        【讨论】:

          猜你喜欢
          • 2011-07-03
          • 2017-02-20
          • 1970-01-01
          • 2022-11-13
          • 2018-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多