I am selecting the last message between two users of a chat system. However, though I am able to select it well, I am not able to order the message according to message that have not been read.
This is what my chat table looks like
CREATE TABLE IF NOT EXISTS `mychat_table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`from_id` int(10) unsigned NOT NULL,
`to_id` int(10) unsigned NOT NULL,
`message` text NOT NULL,
`sent` int(10) unsigned NOT NULL DEFAULT '0',
`read_statu` tinyint(1) unsigned NOT NULL DEFAULT '0',
`is_deleted` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `to` (`to_id`),
KEY `from` (`from_id`),
KEY `direction` (`is_deleted`),
KEY `read` (`read_statu`),
KEY `sent` (`sent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=58 ;
Now to select the last message between the two users I did this
$recup_id = mysqli_query($connection, "SELECT MAX(`id`) AS id FROM mychat_table WHERE (`from_id`='$id' OR `to_id`='$id') AND
(is_deleted!='$id' AND is_deleted >=0) ORDER BY read_statu ASC GROUP BY (IF(`to_id`='$id', `from_id`, `to_id`)) LIMIT 5 ") or die(mysqli_error($connection));
Problem
Normally I thought when I do ORDER BY read_statu ASC it will display the message with the status 0 first and so on and so forth but it does not.
How to display the messages between those users by ordering in such a way that it will first display messages which read_statu=0 before displaying those which read_statu are superior to 0 ?
You are right, that ORDER BY read_status ASC will give you a list ordered by read status, BUT
To actually get the result you want, you could simplify your query in order to display the last five messages giving unread ones precedence:
SELECT * FROM mychat_table
WHERE (`from_id`='$id' OR `to_id`='$id') AND (is_deleted!='$id' AND is_deleted >=0)
ORDER BY read_statu ASC, id DESC
LIMIT 5
If you want the result tidy for display you could use this
SELECT (IF(`to_id`='$id', `from_id`, `to_id`)) AS contact, message, read_statu
FROM mychat_table
WHERE (`from_id`='$id' OR `to_id`='$id') AND (is_deleted!='$id' AND is_deleted >=0)
ORDER BY read_statu ASC, id DESC, contact
LIMIT 5
if you need preference to the grouping and not the read_status, then just place contact at the beginning of the ORDER BY clause:
SELECT (IF(`to_id`='$id', `from_id`, `to_id`)) AS contact, message, read_statu
FROM mychat_table
WHERE (`from_id`='$id' OR `to_id`='$id') AND (is_deleted!='$id' AND is_deleted >=0)
ORDER BY contact, read_statu ASC, id DESC
LIMIT 5
I don't have your data to play around with, so please try the order parameter in different order until you have the desired result, this should get you there.
If you just want to see the last message (preferably unread) from each user (only one message per user) and you can live with just having user id and message text (which should be enough for display) then try this:
SELECT DISTINCT from_id, (
SELECT message FROM mychat_table m2
WHERE to_id='$id' AND m2.from_id=m1.from_id
ORDER BY read_statu ASC, id DESC
LIMIT 1
) AS message FROM mychat_table m1
WHERE to_id='$id'
LIMIT 5