【问题标题】:MySQL get ordered list of contacts by last message sent/receivedMySQL按发送/接收的最后一条消息获取联系人的有序列表
【发布时间】:2018-02-20 11:16:09
【问题描述】:

这是我的情况,我有两张桌子,一张是关于朋友的,另一张是关于消息的。 好友表是这样的:

user_id|friend_id|accepted
  12   |   1      |   1
  13   |   1      |   1
   1   |   3      |   1

accepted 可以是 0 或 1。(1 接受,0 否)

消息表

message|time    |user_id|receiver_id
  hi!  | 1328688|   1   |   12
  hey  | 1343409|   12  |   1

时间是一个时间戳,所以我需要按顺序列出 每个朋友的最高时间戳

我需要按最后一条消息(发送/接收)的顺序列出所有联系人(接受 = 1)。 换句话说,我需要按发送者和接收者分组,并且只从每个朋友那里取一个值(最后一个)。 用户“12”可以在user_id 或friend_id 中,在user_id 和receiver_id 中......所以我需要检查两者。

有人可以帮助我吗?谢谢你们!

编辑 我的查询:

SELECT * FROM friends,messages
                         WHERE  (friends.user_id='$my_id'
                         OR  friends.friend_id ='$my_id'
                         AND friends.accepted='1')
                         AND messages.user_id='$my_id'
                         OR messages.receiver_id='$my_id'

                         GROUP BY  friends.friend_id
                         ORDER BY messages.time DESC");

我尝试了 INNER JOIN,但这太疯狂了(我对 mysql 不太擅长)

编辑 2

消息表

朋友桌

EDIT 3 $my_id 是获取我的 user_id 的变量

【问题讨论】:

  • 你能展示你目前尝试过的查询吗?
  • so i need to list the highest number before the others about the chat 的真正含义是什么?
  • 示例数据有点短。每个表一个记录不会让我们对您的数据有很好的感觉,也不知道您的数据是什么样的。
  • 已编辑!好的@RaymondNijland,如果您愿意,我可以将数据添加到表中。查询的逻辑就像 facebook messanger。

标签: php mysql join


【解决方案1】:

已解决,此查询对我有用

SELECT messages.* FROM messages, (SELECT MAX(id) as lastid
                   FROM messages
                   WHERE (messages.receiver_id = '$myid' OR messages.sender_id = '$myid')

                   GROUP BY CONCAT(LEAST(messages.receiver_id,messages.sender_id),'.',
                   GREATEST(messages.receiver_id, messages.sender_id))) as conversations
                   WHERE id = conversations.lastid
                   ORDER BY messages.time DESC

【讨论】:

    【解决方案2】:

    我不确定这或多或少是你的意思 - 匆忙拼凑起来。

    用于构建示例的数据库架构:

    create table if not exists `friends` (
      `id` int(10) unsigned not null auto_increment,
      `user_id` int(10) unsigned not null,
      `friend_id` int(10) unsigned not null,
      `accepted` tinyint(3) unsigned not null default '0',
      primary key (`id`),
      key `user_id` (`user_id`),
      key `friend_id` (`friend_id`)
    ) engine=innodb auto_increment=3 default charset=utf8;
    
    insert into `friends` (`id`, `user_id`, `friend_id`, `accepted`) values
        (1, 1, 2, 1),
        (2, 1, 3, 0);
    
    create table if not exists `messages` (
      `id` int(10) unsigned not null auto_increment,
      `message` varchar(50) not null default '0',
      `time` timestamp not null default current_timestamp,
      `sender_id` int(11) not null,
      `recipient_id` int(11) not null,
      primary key (`id`),
      key `sender_id` (`sender_id`),
      key `recipient_id` (`recipient_id`)
    ) engine=innodb auto_increment=3 default charset=utf8;
    
    insert into `messages` (`id`, `message`, `time`, `sender_id`, `recipient_id`) values
        (1, 'hi fuddwhack', '2018-02-20 11:32:41', 1, 2),
        (2, 'hello yersel tattyheid', '2018-02-20 11:32:57', 2, 1),
        (3, 'yellow banana', '2018-02-20 11:45:32', 3, 1),
        (4, 'green apple', '2018-02-20 11:45:43', 1, 3),
        (5, 'orange shoes', '2018-02-20 10:46:12', 2, 1),
        (6, 'red pineapple', '2018-02-20 11:46:27', 2, 3);
    
    create table if not exists `users` (
      `uid` int(10) unsigned not null auto_increment,
      `name` varchar(50) not null default '0',
      primary key (`uid`)
    ) engine=innodb auto_increment=4 default charset=utf8;
    
    insert into `users` (`uid`, `name`) values
        (1, 'daphne'),
        (2, 'velma'),
        (3, 'wilma');
    

    显示表格和数据的基本查询

    mysql> describe friends;
    +-----------+---------------------+------+-----+---------+----------------+
    | Field     | Type                | Null | Key | Default | Extra          |
    +-----------+---------------------+------+-----+---------+----------------+
    | id        | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
    | user_id   | int(10) unsigned    | NO   | MUL | NULL    |                |
    | friend_id | int(10) unsigned    | NO   | MUL | NULL    |                |
    | accepted  | tinyint(3) unsigned | NO   |     | 0       |                |
    +-----------+---------------------+------+-----+---------+----------------+
    
    mysql> describe messages;
    +--------------+------------------+------+-----+-------------------+----------------+
    | Field        | Type             | Null | Key | Default           | Extra          |
    +--------------+------------------+------+-----+-------------------+----------------+
    | id           | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
    | message      | varchar(50)      | NO   |     | 0                 |                |
    | time         | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
    | sender_id    | int(11)          | NO   | MUL | NULL              |                |
    | recipient_id | int(11)          | NO   | MUL | NULL              |                |
    +--------------+------------------+------+-----+-------------------+----------------+
    
    mysql> describe users;
    +-------+------------------+------+-----+---------+----------------+
    | Field | Type             | Null | Key | Default | Extra          |
    +-------+------------------+------+-----+---------+----------------+
    | uid   | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(50)      | NO   |     | 0       |                |
    +-------+------------------+------+-----+---------+----------------+
    
    mysql> select * from messages;
    +----+------------------------+---------------------+-----------+--------------+
    | id | message                | time                | sender_id | recipient_id |
    +----+------------------------+---------------------+-----------+--------------+
    |  1 | Hi Fuddwhack           | 2018-02-20 11:32:41 |         1 |            2 |
    |  2 | hello yersel tattyheid | 2018-02-20 11:32:57 |         2 |            1 |
    |  3 | Yellow banana          | 2018-02-20 11:45:32 |         3 |            1 |
    |  4 | green apple            | 2018-02-20 11:45:43 |         1 |            3 |
    |  5 | orange shoes           | 2018-02-20 10:46:12 |         2 |            1 |
    |  6 | red pineapple          | 2018-02-20 11:46:27 |         2 |            3 |
    +----+------------------------+---------------------+-----------+--------------+
    
    mysql> select * from friends;
    +----+---------+-----------+----------+
    | id | user_id | friend_id | accepted |
    +----+---------+-----------+----------+
    |  1 |       1 |         2 |        1 |
    |  2 |       1 |         3 |        0 |
    +----+---------+-----------+----------+
    

    查询以查找从用户到收件人的消息,反之亦然

    select * from messages m
      where 
        m.sender_id=( select f.user_id from friends f where f.friend_id=m.recipient_id and f.accepted=1 )
        or
        m.recipient_id=( select f.user_id from friends f where f.friend_id=m.sender_id and f.accepted=1 )
        order by m.time;
    
    
    +----+------------------------+---------------------+-----------+--------------+
    | id | message                | time                | sender_id | recipient_id |
    +----+------------------------+---------------------+-----------+--------------+
    |  5 | orange shoes           | 2018-02-20 10:46:12 |         2 |            1 |
    |  1 | Hi Fuddwhack           | 2018-02-20 11:32:41 |         1 |            2 |
    |  2 | hello yersel tattyheid | 2018-02-20 11:32:57 |         2 |            1 |
    +----+------------------------+---------------------+-----------+--------------+
    

    【讨论】:

    • 谢谢!但是我有一个问题,我需要按发件人和收件人分组,所以我只需要每个朋友的一个值(最后一个)
    【解决方案3】:

    你需要的是:

    select f.user_id from friends f 
    left outer join messages m on (f.user_id = m.user_id)
    left outer join messages m2 on (f.user_id = m.receiver_id)
    where f.accepted = 1
    group by f.user_id
    order by m.time desc, m2.time desc
    

    【讨论】:

    • 谢谢阿图尔,但我需要按发件人和收件人分组,所以我只需要一个值(最后一个)为每个朋友。我想这个查询组只有user_id,对吧?
    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 2020-02-26
    • 2020-09-18
    • 1970-01-01
    • 2019-05-10
    • 2017-05-24
    • 2015-08-13
    • 2018-04-20
    相关资源
    最近更新 更多