2

考虑下表:

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
)

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

4

6 回答 6

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 纠正我的答案!

于 2012-07-11T09:37:27.333 回答
1

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

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

触发文档

于 2012-07-11T09:19:47.317 回答
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

注意:我没有测试这个。

于 2012-07-11T09:13:44.647 回答
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

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

于 2012-07-11T09:14:12.870 回答
1

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

UPDATE users u
 SET u.messages =
      (  SELECT COUNT (*)
           FROM messages m
       GROUP BY user_id
         HAVING u.user_id = m.user_id);
于 2012-07-11T09:35:30.793 回答
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
于 2012-07-11T09:10:37.983 回答