MySql ifnull 和计数错误?

MySql ifnull and count bug?

MySql版本:5.7.18-15-log,

我同学问了一个问题:

SELECT 
  COUNT(1) Counts, 
  IFNULL((SELECT SUM(c.RealMoney) FROM PayRecord c WHERE a.id=c.orderid), 0) money
FROM `Order` a
WHERE a.UserId ='not exists user id';

他得到了一个结果:

Counts:0 money 8000

, 他问为什么???没有记录,为什么有钱???

我试了一下,发现好像是个bug,例如:

SELECT
  COUNT(1) Counts, 
  IFNULL((SELECT c.RealMoney FROM PayRecord c WHERE a.id=c.orderid), 0) money
FROM `Order` a
WHERE  a.id='bc7ba7ed-44f2-4686-b5ae-df65e8cc566f';

return

Counts:1 money:8622

SELECT 
  COUNT(1) Counts, 
  IFNULL((SELECT SUM(c.RealMoney) FROM PayRecord c WHERE a.id=c.orderid), 0) money
FROM `Order` a
WHERE a.UserId ='not exists user id';

return

Counts:0 money:8622

好像第一个sql会被缓存,
第二个 sql 将使用此缓存...

DDL 喜欢 :

CREATE TABLE `Order` (
  `Id` char(36) NOT NULL ,
  `UserId` char(36) NOT NULL ,
  ......,
  PRIMARY KEY (`Id`,`CreateTime`),
  KEY `idx_RestId` (`RestId`),
  KEY `idx_CreateTime` (`CreateTime`),
  KEY `idx_UserId` (`UserId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
/*!50500 PARTITION BY RANGE  COLUMNS(CreateTime)
(
 PARTITION p201712 VALUES LESS THAN ('2018-01-01') ENGINE = InnoDB,
 PARTITION p201801 VALUES LESS THAN ('2018-02-01') ENGINE = InnoDB) */


CREATE TABLE `PayRecord` (
  `Id` char(36) NOT NULL ,
  `OrderId` char(36) NOT NULL ,
  `RealMoney` int(11) NOT NULL ,
  .......
  PRIMARY KEY (`Id`,`CreateTime`),
  KEY `idx_OrderId` (`OrderId`),
  KEY `idx_PayId` (`PayId`),
  KEY `idx_CreateTime` (`CreateTime`),
  KEY `idx_BrandId_RestId` (`BrandId`,`RestId`),
  KEY `idx_RestId` (`RestId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(CreateTime)
(
 PARTITION p201712 VALUES LESS THAN ('2018-01-01') ENGINE = InnoDB,
 PARTITION p201801 VALUES LESS THAN ('2018-02-01') ENGINE = InnoDB) */

我的问题是: 为什么Count return没有记录, 但是 IFNULL 有价值???

为什么你看到你观察到的东西的逻辑是 COUNT 是一个 聚合 函数。在没有 GROUP BY 的情况下使用时,它将 return 整个 table 的计数。同样重要的是,它总是 return 一条记录,即使实际 table 中没有任何记录。在 select 子句中使用 COUNT 也意味着只能出现其他聚合函数或标量常量。您看到一笔钱的原因是它来自生成单个标量值的子查询。

虽然这可能很难区分,但它肯定不是 MySQL 中的错误。