mysql - 计数查询未正确分组

标签 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

最佳答案

与标准 SQL 不同,MySQL 允许您在字段列表(SELECT 子句)中包含不在 GROUP BY 中且不包含的列。聚合列 — 请参阅 http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html - 但你必须小心,否则你可能会得到不可预测的结果。在您的情况下,您正在GROUPBYmh.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

它应该做你想做的事。

关于mysql - 计数查询未正确分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9213102/

相关文章:

sql - 多次计算同一列,已分组

SQL从一个表中收集数据,同时计算另一个表中的记录

mysql - ODBC select 语句获取 bool 值

mysql - App Engine - Google Cloud SQL - jUnit 的本地 MySQL 数据库 - 未找到 rdbms 包

mysql - 使用 Mac OSX 10.6 为 Ruby on Rails 安装 mysql2 gem

php - 使用 PHP 时区偏移

c# 计算列表中一定长度的字符串

mysql - 计算两次之间的分钟数并将其除以记录数

在具有 GROUP BY 的 SELECT 语句中用于 COUNT 的 SQL WHERE

mysql - GORM withCriteria 返回意外的重复结果