以下が役に立つことを証明可能性があります
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varbinary(32) not null,
unique key users_username_idx(username)
)engine=innodb;
insert into users (username) values
('f00'),('foo'),('bar'),('bAr'),('bish'),('bash'),('bosh');
drop table if exists picture;
create table picture
(
picture_id int unsigned not null auto_increment primary key,
user_id int unsigned not null, -- owner of the picture, the user who uploaded it
tot_votes int unsigned not null default 0, -- total number of votes
tot_rating int unsigned not null default 0, -- accumulative ratings
avg_rating decimal(5,2) not null default 0, -- tot_rating/tot_votes
key picture_user_idx(user_id)
)engine=innodb;
insert into picture (user_id) values
(1),(2),(3),(4),(5),(6),(7),(1),(1),(2),(3),(6),(7),(7),(5);
drop table if exists picture_vote;
create table picture_vote
(
picture_id int unsigned not null,
user_id int unsigned not null,-- voter
rating tinyint unsigned not null default 0, -- rating 0 to 5
primary key (picture_id, user_id)
)engine=innodb;
delimiter #
create trigger picture_vote_before_ins_trig before insert on picture_vote
for each row
proc_main:begin
declare total_rating int unsigned default 0;
declare total_votes int unsigned default 0;
if exists (select 1 from picture_vote where
picture_id = new.picture_id and user_id = new.user_id) then
leave proc_main;
end if;
select tot_rating + new.rating, tot_votes + 1 into total_rating, total_votes
from picture where picture_id = new.picture_id;
-- counts/stats
update picture set
tot_votes = total_votes,
tot_rating = total_rating,
avg_rating = total_rating/total_votes
where picture_id = new.picture_id;
end proc_main #
delimiter ;
insert into picture_vote (picture_id, user_id, rating) values
(1,1,5),(1,2,3),(1,3,3),(1,4,2),(1,5,1),
(2,1,1),(2,2,2),(2,3,3),(2,4,4),(2,5,5),(2,6,1),(2,7,2),
(3,1,5),(3,2,5),(3,3,5),(3,4,5),(3,5,5),(3,6,5),(3,7,5);
select * from users order by user_id;
select * from picture order by picture_id;
select * from picture_vote order by picture_id, user_id;
あなたの基準は完全な意味がありません。どのように投票を集計したいですか?あなたは簡単なカウントをしていますか?それが単なる数であれば、投票者を一度カウントするのではなく、なぜ最新の投票者が必要なのかは理解できません。 –
@アリソン:私が理解しているように、ユーザーが投票を変更した可能性があるので、OPは最後に投票したものを取得したいと考えています。 @ジョーンブリットン:新しい行を作成するのではなく、ユーザーが投票を更新したときに同じ行を再利用するだけの理由はありますか?そうすれば、ユーザーの投票は常に最新のものになります。 –
@musicfreak、あなたは正しいです。私は行を更新することができたかもしれませんが、簡単にするために、私はすべての投票を記録しました。誰が投票を変更したのかを見ることができるのは面白いと思った。 – johndbritton