views:

110

answers:

3

I have a table 'games' for a football league as follows:

date    home_team_id    away_team_id    home_score      away_score
 -          1                 2              6             21
 -          3                 1              7             19

I can't figure out how to dynamically generate a list of team ID's ordered by Wins (then points for if poss)?

--

I have this query which works fine when I have a $team_id but of cause then I can only do 1 team at a time, and that doesn't allow for ordering at query level

((SELECT COUNT(*) FROM `games` WHERE ((`home_score` > `away_score`) AND `home_team_id` = '.$team_id.')) + 
(SELECT COUNT(*) FROM `games` WHERE ((`home_score` < `away_score`) AND `away_team_id` = '.$team_id.'))) AS `wins`

I wonder if i can use this with some form of GROUP, or mySQL can know the $team_id itself? I've also tried some multiple JOINs with the 'team' table but they didn't work either.

Thanks,

Dan

+1  A: 

Maybe this is what you are looking for?

SELECT all_wins.team_id, SUM(all_wins.wins)
FROM (
  SELECT 
     home_team_id as team_id, 
     SUM(IF(home_score > away_score,1,0)) as wins,
     SUM(home_score - away_score) as points
  FROM games
  GROUP BY home_team_id
  UNION ALL
  SELECT 
     away_team_id as team_id, 
     SUM(IF(away_score > home_score,1,0)) as wins,
     SUM(away_score - home_score) as points
  FROM games
  GROUP BY away_team_id
) all_wins
GROUP BY all_wins.team_id
ORDER BY SUM(all_wins.wins), SUM(all_wins.points)

ETA: Original answer wasn't complete, I think this should be better.

The inner two queries that are UNION'd together are getting the home and away wins for each team. The outer query simply sums up the home and away wins for the total win count.

Eric Petroelje
Within the UNION do you also need `(home_score - away_score) as points` for home win and `(away_score - home_score) as points` for away win and then `SUM(all_wins.points)` to give a second order by clause?
Dave Anderson
@Dave - I think you are right. I missed that part of his question. Edited my answer to add that.
Eric Petroelje
It's also missing the FROM gamesin the two inner SELECT querys - but this one is working perfectly for me - this query also really nicely scales to add lots of other stats such as GP, L, T, W%, Pts. for, Pts. against etc.I like this one - thanks.
Dan
@Dan - good point, fixed my answer for posterity :)
Eric Petroelje
+4  A: 

Let's do it step by step:

Select the won games at home and the score at home:

   SELECT COUNT(*) as wins, SUM(G.home_score) as score FROM games G WHERE 
      G.team_id = T.team_id #See 3. query and you'll understand
      G.home_score > away_score

Let's call this result HOME_GAMES.

Select the won games and the score of away games:

SELECT COUNT(*) as wins, SUM(G.away_score) as score FROM games G
WHERE 
  G.team_id = T.team_id #See 3. query and you'll understand
  G.away_score > G.home_score

Let's call this result AWAY_GAMES.

Select the total won games and the total score:

   SELECT (A.wins + H.wins) AS total_wins, (A.score + H.score) AS total_score FROM
   (AWAY_GAMES) AS A, (HOME_GAMES) AS H, teams T 
   ORDER BY total_wins, total_score

==> Put all together by substituting AWAY_GAMES and HOME_GAMES:

SELECT (A.wins + H.wins) AS total_wins, (A.score + H.score) AS total_score FROM 
  (SELECT COUNT(*) as wins, SUM(G.away_score) as score FROM games G
   WHERE 
     G.team_id = T.team_id #See 3. and you'll understand
     G.away_score > G.home_score) AS A, 

   (SELECT COUNT(*) as wins, SUM(G.home_score) as score FROM games G 
   WHERE 
      G.team_id = T.team_id #See 3. and you'll understand
      G.home_score > away_score) AS H, 

   teams T
   ORDER BY total_wins, total_score 
Simon
that's an awesome query - thanks, still figuring out what you've got here. This really is much more difficult then initially appears eh!
Dan
A: 

Based on Eric's solution - here is my final query if anyone else has a similar problem - thanks for everyones help.

SELECT `teams`.`id`, `teams`.`name`,
        SUM(`all_wins`.`gp`) AS `gp`,
        SUM(`all_wins`.`w`) AS `w`, SUM(`all_wins`.`l`) AS `l`, SUM(`all_wins`.`t`) AS `t`,
        SUM(`all_wins`.`ptf`) AS `ptf`, SUM(`all_wins`.`pta`) AS `pta`
FROM (
  SELECT
     `home_team_id` as `team_id`,
     COUNT(`home_score`) AS `gp`,
     SUM(IF(`home_score` > `away_score`,1,0)) as `w`,
     SUM(IF(`home_score` < `away_score`,1,0)) as `l`,
     SUM(IF(`home_score` = `away_score`,1,0)) as `t`,
     SUM(IFNULL(`home_score`,0)) as `ptf`,
     SUM(IFNULL(`away_score`,0)) as `pta`
    FROM `games`    
  GROUP BY `home_team_id`
  UNION ALL
  SELECT
     `away_team_id` as `team_id`,
     COUNT(`home_score`) AS `gp`,
     SUM(IF(`away_score` > `home_score`,1,0)) as `w`,
     SUM(IF(`away_score` < `home_score`,1,0)) as `l`,
     SUM(IF(`away_score` = `home_score`,1,0)) as `t`,
     SUM(IFNULL(`away_score`,0)) as `ptf`,
     SUM(IFNULL(`home_score`,0)) as `pta`
    FROM `games`

  GROUP BY `away_team_id`
) `all_wins`
LEFT JOIN `teams` ON `all_wins`.`team_id` = `teams`.`id`
GROUP BY `all_wins`.`team_id`
ORDER BY SUM(`all_wins`.`w`) DESC, SUM(`all_wins`.`ptf`) DESC
Dan