【问题标题】:What is the reason the counts are different in the mysql queries?mysql查询中计数不同的原因是什么?
【发布时间】:2013-08-05 14:17:56
【问题描述】:

当我使用SQL_CALC_FOUND_ROWS 运行以下查询或使用IN 子句在子查询中指定所有颜色RED,BLUE,YELLOW 时,我得到198 的记录计数。但是当我单独做每种颜色时,我得到一个COUNT,加起来就是248 (72 + 59 + 118)。额外的 50 行从何而来?我原以为如果我单独完成它们然后将它们相加,我会得到198,但我得到的是248。我是否正在查看 IN 子句如何不正确地工作?我更喜欢使用COUNT 而不是SQL_CALC_FOUND_ROWS,因为我发现SQL_CALC_FOUND_ROWS 要慢得多(+3 秒)

以下是一些统计数据:

1. I am running MySQL Version: 5.5.2 
2. The tables engine is INNODB.
3. All the `CHECK TABLE .... EXTENDED` return OK.

-- Returns 198
SELECT SQL_CALC_FOUND_ROWS DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.PersonId = p.Id
WHERE p.Name = 'John Doe' AND c.ColorName IN ('YELLOW','RED','BLUE');
SELECT FOUND_ROWS();

-- Returns 198
SELECT COUNT(1) as MyCount FROM (SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.PersonId = p.Id
WHERE p.Name = 'John Doe' AND c.ColorName IN ('YELLOW','RED','BLUE')) all;

-- Returns 72
SELECT COUNT(1) as MyCount FROM (SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.PersonId = p.Id
WHERE p.Name = 'John Doe' AND c.ColorName IN ('RED')) red;

-- Returns 59
SELECT COUNT(1) as MyCount FROM (SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.PersonId = p.Id
WHERE p.Name = 'John Doe' AND c.ColorName IN ('BLUE')) blue;

-- Returns 118
SELECT COUNT(1) as MyCount FROM (SELECT DISTINCT p.* FROM Persons AS p
INNER JOIN Colors AS c ON c.PersonId = p.Id
WHERE p.Name = 'John Doe' AND c.ColorName IN ('YELLOW')) yellow;

【问题讨论】:

标签: mysql count mysql-5.5


【解决方案1】:

这样的事情正在发生:

Persons

ID  Name
--  ------------
 1  John Doe
 2  Xaisoft

Colors

PersonID  ColorName
--------  ---------
       1  Red
       1  Yellow
       2  Yellow

现在在加入Colors 时查询Persons.* 以获得John Doe

 SELECT p.*
 FROM Persons p
 INNER JOIN Colors C ON c.PersonID = p.ID
 WHERE p.Name = 'John Doe';

您的结果将是一个p.*对于 John Doe 下的每种颜色

ID  Name
--  ------------
 1  John Doe
 1  John Doe

如果您对此应用COUNT DISTINCT,您最终会得到1

如果您分别计算RedYellow,则每个查询都会得到一个。把它们加起来,你会得到2


这样看:如果你扔掉 COUNT 而只是 SELECT DISTINCT Persons.* 你会得到这些结果:

John Doe 的红色或黄色

 SELECT DISTINCT p.*
 FROM Persons p
 INNER JOIN Colors C ON c.PersonID = p.ID
 WHERE p.Name = 'John Doe'
   AND c.ColorName IN ('RED', 'YELLOW');

ID  Name
--  ----------
 1  John Doe

红色仅适用于 John Doe

 SELECT DISTINCT p.*
 FROM Persons p
 INNER JOIN Colors C ON c.PersonID = p.ID
 WHERE p.Name = 'John Doe'
   AND c.ColorName IN ('RED');

ID  Name
--  ----------
 1  John Doe

黄色只代表 John Doe

 SELECT DISTINCT p.*
 FROM Persons p
 INNER JOIN Colors C ON c.PersonID = p.ID
 WHERE p.Name = 'John Doe'
   AND c.ColorName IN ('YELLOW');

ID  Name
--  ----------
 1  John Doe

【讨论】:

  • 但我正在将 DISTINCT COUNT 应用于个人。
  • 但是您的独特计数仅基于Persons 表,而不是基于人和颜色。我在答案中添加了一个示例;看一看。如果这没有意义,请尝试从SELECT * FROM 而不是SELECT COUNT(1) as MyCount FROM 开始运行上面的第二到第五个查询。您将在查询 3、4 和 5 中获得重复名称。由于DISTINCT,这些名称不会在查询 2 中重复。
  • 我在这里修改了我的查询以查看从内部表中实际返回的内容,我确实注意到重复或不明确的值可以解释额外的行。感谢您为我指明正确的方向。老实说,我仍然没有 100% 完全理解它,但我已经完成了一半 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 2017-04-10
相关资源
最近更新 更多