带有 LEFT JOIN 和 GROUP BY 的 COUNT(*) 在 MySQL 中包含 NULL

Posted

技术标签:

【中文标题】带有 LEFT JOIN 和 GROUP BY 的 COUNT(*) 在 MySQL 中包含 NULL【英文标题】:COUNT(*) with LEFT JOIN and GROUP BY to include NULL in MySQL 【发布时间】:2017-04-16 13:28:54 【问题描述】:

我正在尝试从包含外部表中出现计数的表中获取结果。此表可以有 0 次或多次出现。

如下例所示:

表格:颜色

+------+---------+
|  id  |   name  |
+------+---------+
|  1   |   red   |
|  2   |   blue  |
|  3   |  yellow |
|  4   |  green  |
+------+---------+

桌子:水果

+--------+----------+
|  name  | color_id |
+--------+----------+
| apple  |    1     |
| banana |    3     |
| grape  |    4     |
| lemon  |    3     |
+--------+----------+

所以我需要在水果表中列出每种颜色和出现的情况,返回如下内容:

1, red, 1
2, blue, 0
3, yellow, 2
4, green, 1

我正在尝试这个查询:

SELECT `c`.`id`, `c`.`name`, COUNT(1)
FROM color `c`
LEFT JOIN fruit `f`
ON `c`.`id` = `f`.`color_id`
GROUP BY `c`.`id`

此查询返回的“蓝色”计数为 1,而不是 0。因为“蓝色”颜色没有出现在水果表中

【问题讨论】:

不是 COUNT(1) 总是返回 1 吗? 嗯,你在数 1 的个数,mysql 就是这样做的。把count(1)换成count(f.name),就会统计水果的个数。 @Jerry No, COUNT(anything) 计算遇到的非空值的数量。 并且count(1) 中只有一个非空值 - 数字 1。您可以使用简单查询 SELECT COUNT(1) 进行测试; SELECT COUNT(2) 也返回 1,因为在 COUNT 表达式中仍然只有一个标量值。 @Jerry,是的,不管你用一个bare(FROM-less) SELECT(NULL 文字或空值变量除外)计算什么,结果将始终为 1。如果你SELECT COUNT([any non-null constant or unchanging variable]) FROM [an N rowed table] 你会得到 N。如果你 SELECT COUNT(fieldX) FROM tableY 并且 tableY 中的一半行对 fieldX 有一个空值,你将得到一个等于 tableY 中一半行的数字。 COUNT(1) 等于 1 与计数表达式中的标量值无关; COUNT(DISTINCT [non-null constant...]) 将永远是一个。 【参考方案1】:

这行得通:

SELECT c.id, COUNT(f.name)
FROM color c
LEFT JOIN fruit f ON c.id = f.color_id
GROUP BY c.id

你必须计算一个水果的字段,这样才能返回NULL,它变成一个零。

【讨论】:

【参考方案2】:

你把count(1)换成count(f.color_id)

select  
    c.id
    , c.name
    , count(f.color_id) as [Color Count]
from color as c
    left join fruit as f
    on c.id = f.color_id
group by c.id, c.name

【讨论】:

以上是关于带有 LEFT JOIN 和 GROUP BY 的 COUNT(*) 在 MySQL 中包含 NULL的主要内容,如果未能解决你的问题,请参考以下文章

来自 GROUP_BY 的两个 LEFT JOIN 的 GROUP_CONCAT 的奇怪重复行为

SQL 笔记1,left join,group by,having

Mysql LEFT JOIN GROUP BY LAST 每个表的记录

带有“Group by”、“max”和“join”的 SQL 请求?

SQL sum()后许多字段要group by不使用group by, 改用left join select 需要的字段。哪个方法好?速度快?

使用 LEFT JOIN 的 MySQL 视图中的问题... GROUP BY