views:

87

answers:

3

I have a table of ratings that stores a user ID, object ID, and a score (+1 or -1). Now, when I want to display a list of objects with their total scores, the number of +1 votes, and the number of -1 votes.

How can I do this efficiently without having to do SELECT COUNT(*) FROM rating WHERE (score = +/-1 AND object_id = ..)? That's two queries per object displayed, which is unacceptable. Is the database design reasonable?

+1  A: 

While it doesn't address your question of reasonable design, here's a query that gets you both counts at once:

select
    sum(case when score = 1 then 1 else 0 end) 'positive'
,   sum(case when score = -1 then 1 else 0 end) 'negative'
,   objectId
from
    ratings
where
    objectId = @objectId ...
group by
    objectId
Jeff Meatball Yang
A: 
select object_id, 
       sum(case when score = 1 then 1 else 0) upvotes, 
       sum(case when score = -1 then -1 else 0) downvotes,
       sum(score)
from ratings
group by object_id

Perhaps something like that.

glasnt
(You need object_id in the select too.)
Jim Ferrans
(Why that is does. Thank you, kind sir. This has been edited. The correct answer to this question got it correct first time, and 48 seconds faster than myself, if I recall correctly.)
glasnt
A: 

This should do it:

SELECT
 UserID, ObjectID,
 SUM(CASE WHEN score=1 Then 1 Else 0 End) as UpVotes,
 SUM(CASE WHEN score=-1 Then 1 Else 0 End) as DownVotes,
FROM YourTable
GROUP BY UserID, ObjectID
RBarryYoung