I have 2 tables:
user: id, name
message: sender_id, receiver_id, message, read_at, created_at
There are 2 results I need to retrieve and I'm trying to find the best solution. I have included queries that I'm using in the very end.
I need to retrieve a list of users, and also with each user have information available whether there are any unread messages from each user (them as sender, me as receiver) and whether or not there are any read messages between us ( they send I'm receiver or I send they are receivers)
I need Same as above, but only those members where there has been any messaging between us, sorted by unread first, then by last message received.
Can you advise please? Should this be done with joins or subqueries?
In first case I do not need the count, I just need to know whether or not there is at least one unread message. I'm posting code and my current queries, please have a look when you get a chance:
BTW, everything is the way I want in fist query.
My concern is: In second query I would like to order by messages.created_at, but I dont think I can do that with grouping? And also I dont know if this approach is the most optimized and fast.
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `user` VALUES (1,'User 1'),(2,'User 2'),(3,'User 3'),(4,'User 4'),(5,'User 5');
CREATE TABLE `message` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sender_id` bigint(20) DEFAULT NULL,
`receiver_id` bigint(20) DEFAULT NULL,
`message` text,
`read_at` datetime DEFAULT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `message` VALUES (1,3,1,'Messge',NULL,'2010-10-10 10:10:10'),(2,1,4,'Hey','2010-10-10 10:10:12','2010-10-10 10:10:11'),(3,4,1,'Hello','2010-10-10 10:10:19','2010-10-10 10:10:15'),(4,1,4,'Again','2010-10-10 10:10:25','2010-10-10 10:10:21'),(5,3,1,'Hiii',NULL,'2010-10-10 10:10:21');
SELECT u.*, m_new.id as have_new, m.id as have_any
FROM user u
LEFT JOIN message m_new ON (u.id = m_new.sender_id AND m_new.receiver_id = 1 AND m_new.read_at IS NULL)
LEFT JOIN message m ON ((u.id = m.sender_id AND m.receiver_id = 1) OR (u.id = m.receiver_id AND m.sender_id = 1))
GROUP BY u.id
SELECT u.*, m_new.id as have_new, m.id as have_any
FROM user u
LEFT JOIN message m_new ON (u.id = m_new.sender_id AND m_new.receiver_id = 1 AND m_new.read_at IS NULL)
LEFT JOIN message m ON ((u.id = m.sender_id AND m.receiver_id = 1) OR (u.id = m.receiver_id AND m.sender_id = 1))
where m.id IS NOT NULL
GROUP BY u.id