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 中的错误。
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 中的错误。