It is necessary to extract from the database all chats to which the user is subscribed, there is a trace. tables:
Subscriptions: chats_subscriptions
+-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | uid | int(11) | YES | MUL | NULL | | | cid | int(11) | YES | MUL | NULL | | +-------+---------+------+-----+---------+-------+
Chats: chats
+--------+--------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+-------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | owner | int(11) | NO | | NULL | | | label | varchar(100) | YES | | NULL | | | type | varchar(10) | NO | | private | | | status | int(1) | NO | | 1 | | | date | timestamp | YES | | CURRENT_TIMESTAMP | | +--------+--------------+------+-----+-------------------+----------------+
Messages: messages
+-----------+-----------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+-----------+------+-----+-------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | cid | int(11) | NO | | NULL | | | sender | int(11) | NO | | NULL | | | recipient | int(11) | NO | | NULL | | | date | timestamp | NO | | CURRENT_TIMESTAMP | | | content | text | NO | | NULL | | | del | int(11) | YES | | NULL | | | status | int(11) | YES | | NULL | | +-----------+-----------+------+-----+-------------------+----------------+
With the following query, I'm trying to get all the chats to which the user is subscribed, with the number of unread messages:
SELECT `cs`.`cid`, `ch`.`owner` AS `cOwner`, `ch`.`label` AS `cLabel`, `ch`.`type` AS `cType`, `ch`.`status` AS `cStatus`, `ch`.`date` AS `cDate`, COUNT(`msg`.`id`) AS `countMsg` FROM `chats_subscriptions` `cs` LEFT JOIN `chats` `ch` ON `ch`.`id`=`cs`.`cid` LEFT JOIN `messages` `msg` ON `msg`.`cid`=`ch`.`id` AND `msg`.`del` IS NULL AND `msg`.`status` IS NULL AND `msg`.`recipient`=`cs`.`uid` WHERE `cs`.`uid` = 2
Such a request does not work quite correctly, it retrieves the information correctly, but if the user is subscribed to three chat rooms, only one line will return anyway. If you remove LEFT JOIN messages
, then everything works correctly, but you need to retrieve the number of messages (I also want to add the text of the last unread message). Tell me, what cant?
And by the way, if in your opinion this is a curved structure of the database, I’ll be happy to hear your more optimal suggestions! (the task was this: to make correspondence in HP on the site with the ability to add / delete interlocutors, so I decided to present everything in the form of chats with subscriptions to them)
! UPDATE 3:
I tried to make such a request, everything seems to be correct, but it extracts only one line, although there are more subscriptions (chats from the user):
SELECT cs.cid, u.login AS cLogin, u.ava AS cAva, ch.owner AS cOwner, lm.content AS lmContent, lm.lmDate AS lmDate, ch.label AS cLabel, ch.type AS cType, ch.status AS cStatus, ch.date AS cDate,COUNT(*) AS countMsg FROM chats_subscriptions cs INNER JOIN users u ON u.id=cs.uid INNER JOIN chats ch ON ch.id=cs.cid LEFT JOIN messages msg ON msg.cid=ch.id AND msg.del IS NULL AND msg.status IS NULL AND msg.recipient=cs.uid JOIN ( SELECT lm.id, lm.content, lm.cid, lm.date AS lmDate FROM messages lm WHERE lm.status IS NULL AND lm.date = ( SELECT MAX(date) FROM messages GROUP BY lm.id HAVING lm.id ) GROUP BY lm.cid ) lm ON lm.cid = cs.cid WHERE cs.uid = 2 GROUP BY cs.cid
Maybe somewhere is missing something or something extra? I can not understand...