mysql sum()按条件求和、count()按条件计数
1.情景展示
在实际开发过程中,往往会有根据不同条件进行分组求和的需求,在mysql中如何实现?
表SC_PERSON_INFO有HEALTH_CODE字段,该字段有不同的值,对应不同的含义,现在需要根据每种状态分别对其进行计数统计,如何实现?
2.sum()按条件求和
语法1:常见用法
SUM(IF(EXPR, column, 0))
表示的含义是:如果满足表达式expr,+column字段在对应列的值;否则,+0。
语法2:延伸用法
SUM(IF(EXPR, 1, 0))
表示的含义是:如果满足表达式expr,+1;否则,+0(也就是不加);
多个表达式之间可以"or"、"||"表示“或”,具体含义是:多个条件满足其中一个即可。
SELECT
T2.ORGCODE,
SUM(IF(T2.HEALTH_CODE = 1 || T2.HEALTH_CODE IS NULL, 1, 0)) LVMA,
SUM(IF(T2.HEALTH_CODE = 2, 1, 0)) HUANGMA,
SUM(IF(T2.HEALTH_CODE = 3, 1, 0)) HONGMA
FROM
BASE_ORG_INFO T1,
SC_PERSON_INFO T2
WHERE T1.ORGCODE = T2.ORGCODE
GROUP BY T2.ORGCODE;
执行结果如下:

3.count()按条件计数
我们可以看到:用sum(if())也能实现按条件计数的功能;
那用count()可以实现吗?
这里先回忆一下:count(*),count(1)和count(column)的区别。
它们三个的共同点在于:都能实现对表的行数进行计数统计;
在只对某一列数进行统计时,并且,如果该列的某些行的数据为NULL时,区别在于:
count(*)和count(1)会将其统计在内(空行也是行);
count(column)不会将空行统计在内(只对有值的行进行计数)。
所以,利用count()函数的这个特性,我们就能实现:按条件进行计数啦。
语法:
COUNT(IF(EXPR, 1, NULL))
代表的含义是:如果满足表达式,该行此列的值就为1,最后进行count计数的时候+1;否则,该行此列的值将被设置成null,由于count的特性,所以,在最后计数的时候,将不会对其进行计数。
注意:这里的1是虚拟的,你可以将其设置成任意值,对于count()函数而言,它仅仅代表这是一个有效的计数而已。
SELECT
t2.ORGCODE,
COUNT(IF(t2.HEALTH_CODE = 1 || t2.HEALTH_CODE IS NULL, 1, NULL)) lvma,
COUNT(IF(t2.HEALTH_CODE = 2, 1, NULL)) huangma,
COUNT(IF(t2.HEALTH_CODE = 3, 1, NULL)) hongma
FROM
base_org_info t1,
sc_person_info t2
WHERE t1.ORGCODE = t2.ORGCODE
GROUP BY t2.ORGCODE;
与sum(if())实现的计数效果,一模一样。

另外,分组查询,当查询的列不是聚合函数列或分组列,而我们又想要将其展示出来时,要求:这些列的值必须相同(distinct=1,有且只有唯一值)。
4.Oracle按条件计数
2022年3月7日19:48:56
在Oracle当中,使用sum()按条件求和与count()按条件计数的用法一模一样,都能实现;
唯一的区别在于:
将if条件改成decode()
SELECT sum(DECODE(B.HYPERTENSION_RISK, '1', 1, 0)) DW
FROM HEALTH_ASSESSMENT_BP B
GROUP BY B.HYPERTENSION_RISK
UNION ALL
SELECT count(DECODE(B.HYPERTENSION_RISK, '1', 1, null)) DW
FROM HEALTH_ASSESSMENT_BP B
GROUP BY B.HYPERTENSION_RISK

2025-05-09 16:12:32
5.补充说明
场景:需要对表字段reportType=1和reportType=2进行分别计数。
错误用法

我们可以看到:
count()里面直接增加筛选条件,是不对的,统计的仍是所有数据,为什么会这样?
COUNT(reportType = '1') 并不是只统计 reportType = '1' 的数量,而是统计该表达式不为 NULL 的次数。
在 MySQL 中,布尔表达式的值为 0(FALSE)、1(TRUE) 或 NULL,所以 reportType = '1' 返回的是 0 或 1,都不是 NULL,因此都会被 COUNT() 统计进去。
正确实现方式1:利用count(字段)特性
SELECT
h.hospitalCode,
COUNT(h.reportType) AS totalAccessNum,
COUNT(IF(h.reportType = '1', 1, NULL)) AS inspectAccessNum,
COUNT(IF(h.reportType = '2', 1, NULL)) AS checkAccessNum
FROM
hraccesslog h
GROUP BY h.hospitalCode;
正确实现方式2:SUM(IF())
SELECT
h.hospitalCode,
COUNT(h.reportType) AS totalAccessNum,
SUM(IF(h.reportType = '1', 1, 0)) AS inspectAccessNum,
SUM(IF(h.reportType = '2', 1, 0)) AS checkAccessNum
FROM
hraccesslog h
GROUP BY h.hospitalCode;
符合条件求和+1,不符条件求和+0。
正确实现方式3:SUM(CASE WHEN THEN)
SELECT
h.hospitalCode,
COUNT(h.reportType) AS totalAccessNum,
SUM(CASE WHEN h.reportType = '1' THEN 1 ELSE 0 END) AS inspectAccessNum,
SUM(CASE WHEN h.reportType = '2' THEN 1 ELSE 0 END) AS checkAccessNum
FROM
hraccesslog h
GROUP BY h.hospitalCode;
2025-05-13 15:17:01
正确实现方式4:利用or null(推荐使用)
语法:COUNT(筛选条件 OR NULL)
SELECT
h.hospitalCode,
COUNT(h.reportType) AS totalAccessNum,
COUNT( h.reportType = '1' OR NULL) AS inspectAccessNum,
COUNT( h.reportType = '2' OR NULL) AS checkAccessNum
FROM
hraccesslog h
GROUP BY h.hospitalCode;
COUNT()函数里面除了筛选条件,还需要追加: OR NULL。
具体含义是:
如果等式成立,也就是true,则count()里面的内容为:TRUE,内容就变成了:COUNT(TRUE),计数自然+1;
反之,等式不成立,则count()里面的内容为:NULL,内容就变成了:COUNT(NULL),因为null不计入统计结果,所以,计数自然+0。
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
相关推荐:
本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/15913081.html
浙公网安备 33010602011771号