问题
this is my situation,I have 2 tables, one about friends, another about messages. Friends table is like this:
user_id|friend_id|accepted
12 | 1 | 1
13 | 1 | 1
1 | 3 | 1
accepted can be 0 or 1. (1 accepted, 0 nope)
Messages table
message|time |user_id|receiver_id
hi! | 1328688| 1 | 12
hey | 1343409| 12 | 1
Time is a timestamp, so i need to list in order by the highest timestamp for each friend.
I need to list all contacts (that are accepted = 1) in order of last message (send/received). In other words, i need to group by sender and receiver, and take only one value (the last) from each friend. The user "12" can be in user_id or friend_id, and in user_id and receiver_id...so i need to check both.
Someone can help me? Thanks guyz!
EDIT my query:
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");
I tried an INNER JOIN, but it's crazy guyz (i'm not so able with mysql)
EDIT 2
Message Table
Friend Table
EDIT 3 $my_id is variable for take my user_id
回答1:
I'm not sure if this is more or less what you mean - hastily cobbled together.
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');
Basic queries to show table and data
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 |
+----+---------+-----------+----------+
Query to find messages from user to recipient and vice-versa
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 |
+----+------------------------+---------------------+-----------+--------------+
回答2:
Solved, this query worked for me
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
回答3:
What you need is:
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
来源:https://stackoverflow.com/questions/48884044/mysql-get-ordered-list-of-contacts-by-last-message-sent-received