计数查询未正确分组

时间:2012-02-09 14:54:28

标签: mysql count

我有一些问题要弄清楚什么似乎很简单,但它让我不知所措。非常感谢任何帮助。

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

我想看到的是每个团队的输赢,但我遇到了问题,因为上面的match_history表每个匹配和每个团队会有多行。

例如:

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', ''),

这是我正在使用的查询,但它将每行计为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

2 个答案:

答案 0 :(得分:1)

与标准SQL不同,MySQL允许您在字段列表(SELECT子句)中包含不在GROUP BY中且不是聚合列的列 - 请参阅{{3 - 但是你必须要小心,否则你会得到不可预知的结果。在您的情况下,您是GROUP BY mh.team_id,因此您可以安全地添加依赖于团队ID的列(例如,mt.name应该是安全的) ,但无法选择mh.outcomem.id,因为这些取决于具体匹配。所以,我会删除这些列。

然后,我们需要将SUM(1-or-0)更改为COUNT(DISTINCT match-ID-or-NULL),以便我们只计算不同的匹配ID:

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

应该做你想做的事。

答案 1 :(得分:0)

我不确定,因为有一段时间没试过sql但试试这个.. 如果它有任何错误,请告诉我

select team_id, count(*)  from match_history
where outcome = 'Win'
group by team_id

如果它有效,那么我们可以将其与损失结合起来

编辑: 这么麻烦的事...... 你最好好好利用这个......我已经花了几天时间(好吧,至少几分钟:P) 我已经在SQL Server中对它进行了测试,以便在需要时将其定制为mysql。 祝好运! :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

结果:

tid win Loss
1   6   0
2   7   0
3   0   3
4   0   8