2010-11-18 40 views
4

Üç sütun 'zaman damgası', 'seçmen' ve 'vote_for' ile votes adlı bir veritabanı tablom var.MySQL'de nasıl oy kullanırım?

Tablodaki her giriş bir oyu temsil eder. Bazı koşullar altında 'vote_for' için oyların tümünü almak istiyorum.

  • Her seçmen tek seçmen En son oy sayımları birden fazla oyların durumunda, sadece bir kez oy kullanabilirsiniz şöyledir:

    koşullardır.

  • Sadece belirtilen bir zamandan önce yapılan oylar sayılır.

+0

Kriteriniz tam anlamı yok. Nasıl oy toplamak istersiniz? Basit bir sayı mı yapıyorsun yoksa başka türlü mi? Eğer sadece bir sayımsa, o zaman sadece bir seçmeni bir kez seçmekten ziyade bir seçmenden en son neye ihtiyaç duyduğunuzu anlamıyor. –

+0

@Alison: Anladığım kadarıyla, bir kullanıcı oylarını değiştirebilirdi, dolayısıyla OP en sonunda oy kullandıkları şeyi almak ister. @johndbritton: Kullanıcı yeni bir tane oluşturmak yerine oyu güncellediğinde neden aynı satırı tekrar kullanamıyorsunuz? Bu şekilde, kullanıcının oyu her zaman günceldir. –

+0

@musicfreak, kesinlikle haklısınız. Satırı güncelleştirebilirdim, ama sadelik uğruna her oyu kaydettim. Kimin oylarını değiştirdiğini görmenin ilginç olacağını düşündüm. – johndbritton

cevap

4

bu deneyin:

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 
+0

Teşekkürler, bu hata "# 1054 - '' yan tümce '' un.lasttime 'bir hata alıyorum rağmen rağmen doğru görünüyor." – johndbritton

+0

belki de takma ad A ve a.lasttime küçük harf olduğu için ... her zaman MySQL'in büyük küçük harf duyarlılığını unutuyorum! – Leslie

0
SELECT voted_for,COUNT(DISTINCT voter) 
FROM votes 
WHERE timestamp < '2010-11-18 21:05:00' 
GROUP BY voted_for 
+0

Bu kadar yakın, ama bence tamamen doğru değil. Sorgu, bir kereden fazla oy veren seçmenlerin son oylarını saydığından emin olmalıdır. Sorgunuz, her bir seçmen tarafından yalnızca bir oy sayıldığından emin olur, ancak en son oylama olduğundan emin olmaz. – johndbritton

+2

Neden sadece, birden fazla kez oy kullanan bir kullanıcı, veritabanındaki satır sayısını azaltmak için 2. giriş oluşturmak yerine mevcut oylarının üzerine yazacak? – Webnet

+0

, oy verilecek tüm kişilerin oy vermeyeceği tüm seçmenleri sayacaktır! – Leslie

0

şu yararlı olabilir:

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; 
+2

sanırım bu farklı bir soruya cevap vereceğini sanıyordum .... – Leslie

+0

bir tetikleyici ve takograf kullanın, buna ek olarak hmmmm seçme sayısını vs. girin. Iç bağlantı ... 10 milyon satır sonra - esneme. –

+0

Buna oy vermeyeceğim çünkü en iyi cevap olduğunu sanmıyorum.Ancak, soru sorucunun istediği şeyi yapmak için farklı ve mükemmel bir şekilde geçerli bir bakış açısı sunma açısından kesinlikle yararlıdır. –

İlgili konular