计算每个用户的消息数

时间:2012-07-11 09:09:02

标签: mysql

考虑以下表格:

users                messages
-----------------    -----------------------
user_id  messages    msg_id user_id content
-----------------    -----------------------
1        0           1      1       foo
2        0           2      1       bar
3        0           3      1       foobar
                     4      3       baz
                     5      3       bar

我想计算每个用户的邮件数量,并将结果插入users.messages,如下所示:

users                
-----------------    
user_id  messages    
-----------------    
1        3           
2        0           
3        2           

我可以使用PHP来执行此操作,伪:

foreach ($user_id in users) {
  $count = select count(msg_id) from messages where user_id = $user_id
  update users set messages = $count
}

但与直接在MySQL中执行的一个查询相比,这可能效率非常低:

UPDATE users SET messages = (
  SELECT COUNT(msg_id) FROM messages
)

但我确定这不是一个正确的查询。因此,任何帮助将不胜感激: - )

6 个答案:

答案 0 :(得分:3)

以下是答案:

UPDATE `users` AS u 
SET u.messages=(SELECT COUNT(*) FROM messages WHERE user_id=u.user_id)

和测试:

http://sqlfiddle.com/#!2/2768b/1

我只是希望这些不是大表,否则可能需要一段时间......

<强>更新 从查询中删除了不必要的JOIN 感谢@Ariel和@Zane Bien纠正我的回答!

答案 1 :(得分:1)

UPDATE users JOIN
       (SELECT user_id, COUNT(msg_id) num FROM messages group by user_id) c
       USING (user_id)
SET users.messages = c.num

注意:我没有测试过这个。

答案 2 :(得分:1)

MySQL允许您在JOIN语句中使用UPDATE操作,如下所示:

UPDATE 
    users a
LEFT JOIN
(
    SELECT user_id, COUNT(1) AS messagecount
    FROM messages
    GROUP BY user_id
) b ON a.user_id = b.user_id
SET 
    a.messages = COALESCE(b.messagecount, 0)

这将使每个相应的用户在messages表中排列他/她的消息计数,因此更新messages列变得简单地引用相应的连接列包含消息计数。

如果用户在messages表格中没有任何消息,则只需将列设置为0

您还可以确保这将非常快速地执行,因为不需要使用低效的子查询(最终在每次迭代时执行),以及连接将通过索引执行的事实。

答案 3 :(得分:1)

假设您知道如何触发查询我会说这个......

只要将消息发布到messages表中并在users表中插入行数,就在插入时创建一个触发器。因此,每次插入新消息时,都不必通过php触发查询。因此,当您要插入新邮件时,您的no消息将自动更新,而当您想要检查特定用户的消息数时,您只需触发选择查询。

Trigger documentation

答案 4 :(得分:1)

这个肯定会奏效。 试试这个:

UPDATE users u
 SET u.messages =
      (  SELECT COUNT (*)
           FROM messages m
       GROUP BY user_id
         HAVING u.user_id = m.user_id);

答案 5 :(得分:0)

试试这个::

UPDATE users u
inner join 
(
  Select user_id, count(1) as number
    from users u inner join messages m on (u.user_id=m.user_id) group by m.user_id 
) as temp_message tm on (u.user_id=tm.user_id)
set u.messages=tm.number