views:

420

answers:

5

I am working on a rankings page for a game and am looking to order the rankings first by wins, and then by losses (in case of people having the same number of wins). The following query works fine in order to make a list in order by wins, but I am not sure how to put losses into this query.

SELECT username, COUNT(id) AS wins 
  FROM tblBattleHistory 
  WHERE battle_type = '0' && outcome = '1' 
  GROUP BY username 
  ORDER BY wins DESC

outcome = '1' means they won, so when outcome = '0' then that means they lost.

A: 

I undestand that my answer is obviosly not what you asked, but... i think instead of getting counts from tblBattleHistory you should add 2 fileds to you Users table (wins, fails) and update them (maybe via insert trigger on tblBattleHistory) so you have all data at hands availabe via simple select.

COTOHA
That would be considered redundant and de-normalization. Don't denormalize unless you have performance problems!
Joe Philllips
If you want to simplify this via a "simple" SELECT then set up a view and do your simple select off that... No need to f**k up the DB design just to have simple queries. You DO know what a view is, right?
gmagana
actually this is neither redundancy nor denormalization. this is just straight forward domain design.there is a user and user has win/loose ratio. this is absolutely not about performance.---as for the view - the view you propose is a direct result of dumb domain models' design (no need to talk that these models are mapped to dumb DB structure)imo, of course :)
COTOHA
+7  A: 

You can do it like this:

SELECT username, SUM(outcome) AS wins, COUNT(*) - SUM(outcome) AS losses
  FROM tblBattleHistory 
  WHERE battle_type = '0'
  GROUP BY username 
  ORDER BY wins DESC, losses
Greg
Looks like this should work. +1
Lior Cohen
Are there ties?
Joe Philllips
This doesn't work if there are ties.
IronGoofy
+1, re @IronGoofy the answer is to get the OP on the right track, u don't need to code it for him ;)
eglasius
Lol, leave it to programmers to complicate something. There was no mention of ties at all in the OP, so why ask it? You may as well as if night-time games count.
gmagana
@gmagana: Attention to detail and foresight is an essential skill
OMG Ponies
Great solution, I was thinking way too complicated trying to have a subquery. Also, I do have ties, but it can still work with ties if I just add "WHERE outcome < '2'" since outcome is set to 2 if it is a tie, and I don't need to know how many ties.
James Simpson
A: 
rockacola
+3  A: 

Here's my idea:

SELECT username, SUM (CASE WHEN outcome = '1' Then 1 Else 0 End) As Wins,
    SUM (CASE WHEN outcome = '0' Then 1 Else 0 End) As Losses
FROM tblBattleHistory 
WHERE battle_type = '0'
GROUP BY username 
ORDER BY wins DESC, Losses ASC

(Depending on your DBMS, you may have to repeat the SUMs in the Order By rather than use the aliases.)

This also allows to to come up with some stranger points schemes, for example for German football (win=3, tie=1 point)

SELECT username, SUM (CASE
    WHEN outcome = '1' Then 3 
    WHEN outcome = '2' Then 1 /* 2 is a tie */
    ELSE 0 End) As Points
etc.
IronGoofy
A: 

This might also work:

SELECT username, SUM(IF(outcome = 1, 1, 0)) AS Wins, SUM(IF(outcome = 0, 1, 0)) AS Losses FROM tblBattleHistory

Bobby

Bobby