Reputation: 1
I'm having some issues figuring out what seems to be simple, but it's eluding me. Any help is much appreciated.
CREATE TABLE IF NOT EXISTS `match_history` (
`id` int(11) NOT NULL auto_increment,
`match_id` int(11) NOT NULL,
`team_id` int(11) NOT NULL,
`player_id` int(11) NOT NULL,
`map` varchar(150) NOT NULL,
`score` int(11) NOT NULL,
`outcome` varchar(25) NOT NULL,
`notes` longtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=271 ;
match_id links to matches.id
team_id links to matchteams.id
player_id links to persons.id
What I want to see is wins and losses per team, but I'm having issues since the match_history table above will have multiple rows per match and per team.
For instance:
INSERT INTO `match_history` (`id`, `match_id`, `team_id`, `player_id`, `map`, `score`, `outcome`, `notes`) VALUES
(221, 44, 2, 124, 'Village', 1570, 'Win', ''),
(220, 44, 2, 115, 'Village', 1600, 'Win', ''),
(219, 44, 2, 92, 'Village', 2740, 'Win', ''),
(218, 44, 4, 105, 'Village',1000, 'Loss', ''),
(217, 44, 4, 111, 'Village', 1220, 'Loss', ''),
(216, 44, 4, 130, 'Village', 1440, 'Loss', ''),
(215, 44, 4, 122, 'Village', 2160, 'Loss', ''),
(214, 44, 4, 130, 'Seatown', 1410, 'Loss', ''),
(213, 44, 4, 122, 'Seatown', 1600, 'Loss', ''),
(212, 44, 4, 111, 'Seatown', 1790, 'Loss', ''),
(211, 44, 4, 105, 'Seatown', 1790, 'Loss', ''),
(210, 44, 2, 113, 'Seatown', 1020, 'Win', ''),
(209, 44, 2, 124, 'Seatown', 1480, 'Win', ''),
(207, 44, 2, 115, 'Seatown', 2850, 'Win', ''),
(208, 44, 2, 92, 'Seatown', 2160, 'Win', ''),
(222, 44, 2, 113, 'Village', 900, 'Win', ''),
(223, 45, 1, 123, 'Hardhat', 2970, 'Win', ''),
(224, 45, 1, 26, 'Hardhat', 2930, 'Win', ''),
(225, 45, 1, 107, 'Hardhat', 1710, 'Win', ''),
(226, 45, 3, 101, 'Hardhat', 1530, 'Loss', ''),
(227, 45, 3, 100, 'Hardhat', 1420, 'Loss', ''),
(228, 45, 3, 125, 'Hardhat', 1010, 'Loss', ''),
(229, 45, 1, 107, 'Seatown', 2520, 'Win', ''),
(230, 45, 1, 123, 'Seatown', 2260, 'Win', ''),
(231, 45, 1, 26, 'Seatown', 1560, 'Win', ''),
(232, 45, 3, 101, 'Seatown', 1510, 25, 3, 42, 0.6, 0, 0, 0, 'Loss', ''),
This is the query I was using, but it's counting each row as 1.
select mh.team_id as team_id, COUNT(distinct(mh.match_id)) as matches,
count(mh.map) as maps, mh.outcome, SUM(IF(mh.outcome='Win',1,0)) as wins,
SUM(IF(mh.outcome='Loss',1,0)) as losses, m.id, mt.name as teamname
FROM match_history mh, matches m, ladders l, match_teams mt
WHERE mh.team_id = mt.id and mh.match_id = m.id and
m.ladder_id = l.id and l.type = 'internal'
GROUP by mh.team_id
ORDER by wins desc
Upvotes: 0
Views: 154
Reputation: 1106
I am not sure since havent tried sql in a while but try this.. let me know if it gives any error
select team_id, count(*) from match_history
where outcome = 'Win'
group by team_id
if it works then we can union it with losses
EDIT: Such a troublesome thing... You better make a good use of this.. i have spent days (well, atleast minutes :P ) getting to this i have tested it in SQL Server to tailor it to mysql if needed. Good Luck! :D
select aa.tid, aa.win, COALESCE(c.loss, 0) from
(SELECT distinct a.team_id tid, COALESCE(b.win, 0) win
FROM [match_history] a
left join
(select team_id, count(*) win
from [match_history]
where outcome = 'Win'
group by team_id) b
on a.team_id = b.team_id)aa
left join
(select team_id, count(*) loss
from [match_history]
where outcome = 'Loss'
group by team_id) c
on aa.tid = c.team_id
Result:
tid win Loss
1 6 0
2 7 0
3 0 3
4 0 8
Upvotes: 0
Reputation: 183582
MySQL, unlike standard SQL, allows you to include columns in the field-list (the SELECT
clause) that aren't in the GROUP BY
and aren't aggregate columns — see http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html — but you have to be careful, or you can get unpredictable results. In your case, you're GROUP
ing BY
mh.team_id
, so you can safely include columns that depend on the team-ID (for example, mt.name
should be safe), but you cannot select mh.outcome
and m.id
, since these depend on the specific match. So, I'll remove those columns.
Then, we need to change the SUM(1-or-0)
to COUNT(DISTINCT match-ID-or-NULL)
so that we only count distinct match-IDs:
select mh.team_id as team_id,
COUNT(distinct(mh.match_id)) as matches,
count(mh.map) as maps,
COUNT(DISTINCT IF(mh.outcome='Win',m.id,NULL)) as wins,
COUNT(DISTINCT IF(mh.outcome='Loss',m.id,NULL)) as losses,
mt.name as teamname
FROM match_history mh,
matches m,
ladders l,
match_teams mt
WHERE mh.team_id = mt.id
and mh.match_id = m.id
and m.ladder_id = l.id
and l.type = 'internal'
GROUP by mh.team_id
ORDER by wins desc
which should do what you want.
Upvotes: 1