mysql 从使用 3 个表的连接中计算

mysql count from joins using 3 tables

我正在尝试构建一个聊天应用程序,其中我有这四个 tables

  1. chat --id,group_id,body,time_posted[时间戳]
  2. chat_groups --建立群组id,name
  3. users_groups --link users to a group, 也定义用户是否盯着这个组 FIELDS::user_id,group_id,stared[bool]
  4. wall_visit --user_id,group_id,last_visit[时间戳]

想法是每个用户都加入一个群组,然后他们 post 在聊天中加入群组。 chat_groups table 只是用来定义房间,而 users_groups 是用来设置成员对这个组的访问权限。

wall_visit table 是一个 table 存储特定用户上次访问特定组(因为它是多对多的你知道..)

现在我要建立的是进入一个查询,

  1. 相关的chat_groups用户
  2. 自用户上次登录(来自设置)以来发送到该组的消息数post
  3. 该组的成员数
  4. 群名

:) 我现在已经尝试了几个小时 :( 我能想出的最好办法

SELECT w.last_visit,access.stared,cg.user_id,u.fullname as username,cg.name as group_name ,cgu.count_members,c.count_msgs,c.time_posted
            FROM `chat_groups`cg
            inner join chat_groups_users access on (access.group_id = cg.id and access.user_id = ?)
            left outer join users u on u.id = cg.user_id
            left join wall_visit w on w.group_id = cg.id
            left  join (select count(*) as count_members,group_id from group_users group by group_id) cgu on cgu.group_id = cg.id
            left join (SELECT count(wv.id) as count_msgs,c.group_id,c.time_posted FROM chats c
left outer join `wall_visit` wv on (wv.group_id is not null and c.group_id = wv.group_id and c.time_posted > wv.last_visit)
group by c.group_id) c on c.group_id = cg.id
            where cg.user_id = 1

此查询有效..ehh,我的主要问题是自 last_visit.

以来群组中的消息计数
  1. 让 message_count 工作的最佳方法是什么:( ??
  2. 这个查询是否可以进一步优化?

感谢 SO 社区 :)

我的第二次尝试

SELECT w.last_visit,access.stared,cg.user_id,u.fullname as username,cg.with_id,uu.fullname as with_name,cg.name as group_name ,cgu.count_members,c.count_msgs,c.time_posted
            FROM `chat_groups`cg
            inner join chat_groups_users access on (access.group_id = cg.id and access.user_id = 1)
            left outer join users u on u.id = cg.user_id
            left join wall_visit w on w.chat_id = cg.id
            left outer join users uu on uu.id = cg.with_id
            left  join (select count(*) as count_members,group_id from chat_groups_users group by group_id) cgu on cgu.group_id = cg.id
            left join (
            SELECT group_id,count(c.id) as count_msgs,time_posted FROM `chats` c inner join wall_Visit wv on wv.chat_id = c.group_id where c.id > wv.last_visit group by c.group_id
            ) c on c.group_id = cg.id
            where cg.user_id = 1

这应该可以解决您的消息计数问题

SELECT 

    `cg`.`user_id`, `cg`.`with_id`, `cg`.`name` AS `group_name`,
    `access`.`stared`,
    `u`.`fullname` AS `username`,
    `w`.`last_visit`,    
    `uu`.`fullname` AS `with_name`, 
    `cgu`.`count_members`, 
    `c`.`count_msgs`, `c`.`time_posted`

FROM `chat_groups` AS `cg`
INNER JOIN `chat_groups_users` AS `access` 
            ON (`access`.`group_id` = `cg`.`id` AND `access`.`user_id` = `cg`.`user_id`)
LEFT OUTER JOIN `users` AS `u` 
            ON (`u`.`id` = `cg`.`user_id`)
LEFT JOIN `wall_visit` AS `w` 
            ON (`w`.`chat_id` = `cg`.`id`)
LEFT OUTER JOIN `users` AS `uu` 
            ON (`uu`.`id` = `cg`.`with_id`)
LEFT JOIN (
    SELECT COUNT(*) AS `count_members`, `group_id` 
    FROM `chat_groups_users` 
    GROUP BY 
        `group_id`
) AS `cgu` 
            ON (`cgu`.`group_id` = `cg`.`id`)
LEFT JOIN (
    SELECT count(`c`.`id`) AS `count_msgs`, `c`.`time_posted` 
    FROM `chats` AS `c` 
    INNER JOIN `wall_visit` AS `wv` 
            ON (`wv`.`chat_id` = `c`.`group_id`) 
    WHERE 
        `c`.`time_posted` > `wv`.`last_visit` 
    GROUP BY 
        `c`.`group_id`
) AS `c` 
            ON (`c`.`group_id` = `cg`.`id`)
WHERE `cg`.`user_id` = 1

否则你必须设置 fiddle