SQL:Null 列的计数不正确

Posted

技术标签:

【中文标题】SQL:Null 列的计数不正确【英文标题】:SQL: Incorrect count on Null column 【发布时间】:2019-01-11 13:19:02 【问题描述】:

mysql SQL 没有为具有空值和非空值的记录返回正确的计数

我在一个包含三列(代码、amt、名称)的表中有以下值

"AMPF";"0.1000";"Amplify Inc";
"AMPF";"0.1000";"Amplify Inc";
"AMPF";"0.2000";"Amplify Inc";
"AMPF";"0.2000";"Amplify Inc";
"AMPF";"0.3000";"Amplify Inc";
"AMPF";"0.3000";"";
"AMPF";"0.4000";"";
"XYZA";"0.1000";"PeterPal Inc";
"XYZA";"0.1000";"PeterPal Inc"

我正在运行以下查询来获取特定项目代码存在的记录数。 SELECT code, name, count(amt) as cnt FROM table group by code order by cnt desc limit 30

SELECT code, name, count(amt) as cnt FROM table group by code order by cnt desc limit 30

理想情况下,预期结果应该是:

AMPF,Amplify Inc,7
XYZA,PeterPal Inc,2

但是,结果却是:

AMPF,Amplify Inc,5
XYZA,PeterPal Inc,2

这表明虽然我在 amt 列上进行计数,但它以某种方式在记录号 6 和 7 中为空的 name 列上进行计数。 对我的代码出了什么问题有任何想法吗?

【问题讨论】:

请始终标记您正在使用的 DBMS! 你的 group by 不应该工作,除非它是 MySQL 并且只有完整的 group by 被禁用。 对不起...这是 MySQL 【参考方案1】:

首先,只需使用count(*)

SELECT code, MAX(name) as name, count(*) as cnt
FROM table 
GROUP BY code 
ORDER BY cnt desc 
LIMIT 30;

发生的情况是看起来像'AMPF' 的值并不是真正的'AMPF'——也就是说,它们不相等。我不知道为什么。它可能是代码开头的空格,可能是不同字符集中的“相似”字符,也可能是隐藏字符。

如果您进一步查看列表,您应该会看到正在计算的其他代码 - 如果您忽略了 LIMIT

我还更改了SELECT,因此NAME 不会取自不确定的行。这只是使用找到的MAX() 值。

【讨论】:

谢谢@GordonLinoff。但是,count(*) 甚至 count(1) 都不起作用。我手动验证了每个值并将其更新为“AMPF”,但仍然没有运气。此外,“select * from table where code='AMPF'”返回 7 行,所以仍然不确定为什么在上述 SQL 中只报告 5 行。【参考方案2】:

不幸的是,这种情况没有直接的答案。按照设计,MySQL count() 函数实际上只计算 NOT NULL 值。但是,可以实施以下两种解决方法:

首先,可以运行单独的 SQL 语句来计算为 NULL 的记录。

其次,如果通过外键可以在另一个表中获得一个(或多个)所需值,则从另一个表中获取这些值,并对第一个表运行计数以获得正确的计数。

PS:我使用第一个来满足我的需要。

【讨论】:

以上是关于SQL:Null 列的计数不正确的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL Developer - 计数函数

SQL-Server:继续最后一个值而不是 NULL,分区不正确

数据库中的sql语句完整性约束

错误代码:1366。不正确的整数值:第 2 行的列“ReportsTo”的“NULL”

Spark UDF 没有正确给出滚动计数

CASE SQL 语句不正确