我有USERS
包含以下字段的表_id
name
number_of_posts
我有POSTS
包含以下字段的表_id
user_id
post_text
users
和posts
之间的关系不是one- to -many
,即一个用户有很多帖子
问题是如何更新number_of_posts
表格中的users
,使其保留posts
表格中的帖子数量
更新
我有这些表填充了大约数百条记录,没有办法使用触发器来更新number_of_posts。
答案 0 :(得分:2)
下面给出的示例脚本显示了如何使用users
加入posts
和LEFT OUTER JOIN
表格来获取与用户关联的帖子数量,然后使用GROUP BY
users 表中的* _id *字段用于获取帖子数。
Click here to view the sample in SQL Fiddle.
查询:
CREATE TABLE users
(
_id INT NOT NULL
, name VARCHAR(30) NOT NULL
);
CREATE TABLE posts
(
_id INT NOT NULL
, _userid INT NOT NULL
, name VARCHAR(30) NOT NULL
);
INSERT INTO users (_id, name) VALUES
(1, 'user 1'),
(2, 'user 2'),
(3, 'user 3');
INSERT INTO posts (_id, _userid, name) VALUES
(1, 1, 'post 1'),
(2, 1, 'post 2'),
(3, 2, 'post 3');
SELECT u._id
, u.name
, COUNT(p._id) number_of_posts
FROM users u
LEFT OUTER JOIN posts p
ON u._id = p._userid
GROUP BY u._id;
输出:
_ID NAME NUMBER_OF_POSTS
--- ------ ---------------
1 user 1 2
2 user 2 1
3 user 3 0
答案 1 :(得分:1)
您可以使用posts表上的触发器执行此操作。每次插入帖子时,请更新users表上的number_of_posts。
请参阅http://dev.mysql.com/doc/refman/5.6/en/triggers.html
更新:完整的解决方案
drop table if exists users;
create table users (
_id bigint unsigned auto_increment primary key,
name varchar(50) not null,
number_of_posts integer not null default 0
);
drop table if exists posts;
create table posts (
_id bigint unsigned auto_increment primary key,
user_id bigint unsigned not null,
post_text text
);
-- Populate with dummy data
insert into users (name) values ('Bob'), ('Sally');
insert into posts (user_id, post_text)
values (1, 'First!!'), (1, 'Second...'),
(2, 'Post 1'), (2, 'another post'), (2, 'more posts');
-- One-time update of users table
update users u
set u.number_of_posts = (
select count(0) from posts p
where u._id = p.user_id
);
-- trigger to keep post count up to date when future posts are made
drop trigger if exists trg_post_count;
delimiter $$
create trigger trg_post_count
after insert on posts
for each row
begin
select count(0) into @post_count
from posts
where user_id = NEW.user_id;
update users
set number_of_posts = @post_count
where _id = NEW.user_id;
end;
$$
delimiter ;
-- test trigger
insert into posts (user_id) values (2);
select * from users;
答案 2 :(得分:1)
作为一次性更新,请尝试此操作,但触发解决方案是使其保持最新状态的正确方法:
UPDATE users AS u SET u.number_of posts = (SELECT COUNT(*) FROM posts AS p WHERE p.user_id=u.user_id)
答案 3 :(得分:0)
正如dwurf建议的那样,我肯定会建议将其置于触发器中以使该字段保持最新状态。但是,我完全不同意他的说法,它应该只是一个在每次更新时递增的数字。这很脆弱且容易出错。您应该使用以下查询来确定每个用户的确切帖子数量:
update
users
set
number_of_posts = (
select
count(0)
from
posts p
where
p.user_id = users.id
)
;