我有一個名爲votes
的數據庫表,其中包含三列「時間戳」,「選民」和「voteed_for」。如何計算MySQL中的投票?
表中的每個條目代表一票。我想在某些條件下爲每個「投票」選出所有選票。
的條件如下:
每個選民可以通過一個單一的選民最近的投票數只能投票一次,在多票的情況。
只有在指定時間之前進行的選票纔會被統計。
我有一個名爲votes
的數據庫表,其中包含三列「時間戳」,「選民」和「voteed_for」。如何計算MySQL中的投票?
表中的每個條目代表一票。我想在某些條件下爲每個「投票」選出所有選票。
的條件如下:
每個選民可以通過一個單一的選民最近的投票數只能投票一次,在多票的情況。
只有在指定時間之前進行的選票纔會被統計。
試試這個:
SELECT voted_for, count(*)
FROM votes v
INNER JOIN (SELECT Voter, Max(timestamp) as lastTime from votes group by Voter) A
on A.Voter = v.voter and a.lasttime = v.timestamp
WHERE timestamp < {date and time of last vote allowed}
Group by voted_for
謝謝,這看起來是正確的,雖然我得到一個錯誤「#1054 - 在'條款'中的未知列'a.lasttime'。」 – johndbritton 2010-11-19 21:25:19
也許是因爲別名是A,而a.lasttime是小寫......我總是忘記了MySQL的大小寫敏感性! – Leslie 2010-11-19 21:45:22
SELECT voted_for,COUNT(DISTINCT voter)
FROM votes
WHERE timestamp < '2010-11-18 21:05:00'
GROUP BY voted_for
這很接近,但我不認爲這是完全正確的。查詢需要確保統計不止一次投票的選民的最新投票。您的查詢確保只計算每個選民的一票,但不能確定它是最新的投票。 – johndbritton 2010-11-18 20:21:52
爲什麼不這樣做,讓不止一次投票的用戶簡單地覆蓋他們現有的投票,而不是創建第二個條目來減少數據庫中的行數? – Webnet 2010-11-18 20:31:07
這將統計所有的選民不是所有的投票人! – Leslie 2010-11-18 21:03:43
下面可能證明是有益的:
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;
我認爲這是設想回答一個不同的問題.... – Leslie 2010-11-18 20:44:43
使用一個觸發器和理貨,你插入與hmmmm選擇計數..內部加入... 1000萬行後 - 打哈欠。 – 2010-11-18 20:57:54
我不會投這個票,因爲我不認爲這是最好的答案。但從提出一種完全有效的方式來完成提問者想要的角度來看,這無疑是有幫助的。 – 2010-11-18 22:40:24
您的標準不作完整意義上的。你想如何計票?你在做簡單的計數或其他嗎?如果只是一個計數,那麼爲什麼你需要最近從選民那裏得到的數據,而不是僅僅統計一次選民。 – 2010-11-18 20:35:59
@Alison:據我瞭解,用戶可能已經改變了他們的投票,所以OP想要得到他們最後投票的東西。 @johndbritton:爲什麼當用戶更新他的投票而不是創建一個新的投票時,你不能重新使用同一行?這樣,用戶的投票總是最新的。 – 2010-11-18 22:09:17
@musicfreak,你完全正確。我本可以更新這一行,但爲了簡單起見,我只記錄了每一票。我認爲能夠看到誰改變了他們的投票會很有趣。 – johndbritton 2010-11-18 22:36:35