考虑以下表格:
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
)
但我确定这不是一个正确的查询。因此,任何帮助将不胜感激: - )
答案 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消息将自动更新,而当您想要检查特定用户的消息数时,您只需触发选择查询。
答案 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