MySQL通过发送/接收的最后一条消息获得有序的联系人列表

时间:2018-02-20 11:16:10

标签: php mysql join

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

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

接受可以是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

消息表 Messages table

朋友表 Friends table

编辑3 $ my_id是变量,用于获取我的user_id

3 个答案:

答案 0 :(得分:1)

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

db schema to build example:

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 |
+----+------------------------+---------------------+-----------+--------------+

答案 1 :(得分:0)

您需要的是:

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

答案 2 :(得分:0)

解决了,此查询对我有用

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