sum 与 count 配合case when 的区别

本文通过具体的SQL案例演示了如何计算学生总人数、男生数、女生数及性别未知数,并提供了两种不同的统计方法。同时对比了COUNT(1)与COUNT(列或表达式)的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

案例表:

create schema test;
create table test.student(id int4, name varchar(20), score int4, course int4, grade int4, sex int2);
 insert into test.student(id, name, score, course, grade, sex) values(1, 'alice', 60, 1,  6, 0), (2,'bob', 60, 1,  6, 0);
insert into test.student(id, name, score, course, grade, sex) values(3, 'cark', 80, 1, 6 , 0);
insert into test.student(id, name, score, course, grade, sex) values(4, 'dock', 100,1,6,0);
insert into test.student(id, name, score, course, grade, sex) values(5,'elic', 70, 1, 5, null);
insert into test.student(id, name, score, course, grade, sex) values(6,'frank', 70, 2, 5, null);
insert into test.student(id, name, score, course, grade, sex) values(7,'grace', 70, 2, 4, null);
insert into test.student(id, name, score, course, grade, sex) values(8,'hill', 60, 1, 4, 1);
insert into test.student(id, name, score, course, grade, sex) values(9,'iris', 80, 2, 4, 1);
insert into test.student(id, name, score, course, grade, sex) values(10,'jacky', 80, 2, 4, 1);

#select * from test.student order by id;
 id | name  | score | course | grade | sex 
----+-------+-------+--------+-------+-----
  1 | alice |    60 |      1 |     6 |   0
  2 | bob   |    90 |      1 |     6 |   0
  3 | cark  |    80 |      1 |     6 |   0
  4 | dock  |   100 |      1 |     6 |   0
  5 | elic  |    70 |      1 |     5 |    
  6 | frank |    70 |      2 |     5 |    
  7 | grace |    50 |      2 |     4 |    
  8 | hill  |    60 |      1 |     4 |   1
  9 | iris  |    80 |      2 |     4 |   1
 10 | jacky |    80 |      2 |     4 |   1
(10 rows)

1、计算全年级总人数,男人数,女生数及性别未知数

方法一:
-- 感谢评论区 AetherTL的反馈
-- 已把 “count(case when sex <> 1 and sex <> 2 then 1 end) 性别未知“ 错误语句修改为“count(case when sex is null then 1 end) 性别未知”。切记不可修改为“count(case when sex <>0 and sex <> 1 then 1 end) 性别未知”, 因为count(sex) 是不会统计为null的元素
-- 为什么 错误语句 “count(case when sex <> 1 and sex <> 2 then 1 end)“ 统计结果为4呢?
-- 因为这句相当于 “count(case when sex = 0 then 1 end)”。
select
count(1) 总人数,
count(case when sex = 0 then 1 end) 男生数,
count(case when sex = 1 then 1 end) 女生数,
count(case when sex is null then 1 end) 性别未知 -- 写成 count(case when sex <>0 and sex <> 1 then 1 end) 还是为空,因为count(sex) 是不会统计为null的元素 
from
test.student;
 总人数 | 男生数 | 女生数 | 性别未知
--------+--------+--------+----------
     10 |      4 |      3 |        3

更正为:
select
    count(1) 总人数,
    sum(case when sex = 0 then 1 end) 男生数,
    sum(case when sex = 1 then 1 end) 女生数,
    sum(case when sex is null then 1 end) 性别未知
from
    test.student;
 总人数 | 男生数 | 女生数 | 性别未知
--------+--------+--------+----------
     10 |      4 |      3 |        3

2、计算四五六三个年级分别的男生数、女生数及性别未知数

方法一:
select
    grade,
    count(1) 总人数,
    sum(case when sex = 0 then 1 else 0 end) 男生数,
    sum(case when sex = 1 then 1 else 0 end) 女生数,
    sum(case when sex is null then 1 else 0 end) 性别未知
from 
    test.student 
group by grade order by grade desc;
 grade | 总人数 | 男生数 | 女生数 | 性别未知
-------+--------+--------+--------+----------
     6 |      4 |      4 |      0 |        0
     5 |      2 |      0 |      0 |        2
     4 |      4 |      0 |      3 |        1
(3 rows)
     
方法二,还能继续使用count 完成嘛?
select
    grade,
    count(1) 总人数,
    count(case when sex = 0 then 1 end) 男生数,
    count(case when sex = 1 then 1 end) 女生数,
    count(case when sex is null then 1 end) 性别未知
from 
    test.student 
group by grade order by grade desc;
 grade | 总人数 | 男生数 | 女生数 | 性别未知
-------+--------+--------+--------+----------
     6 |      4 |      4 |      0 |        0
     5 |      2 |      0 |      0 |        2
     4 |      4 |      0 |      3 |        1
(3 rows)

select
    grade,
    count(1) 总人数,
    count(case when sex = 0 then 1 else 0 end) 男生数,
    count(case when sex = 1 then 1 else 0 end) 女生数,
    count(case when sex is null then 1 else 0 end) 性别未知
from 
    test.student 
group by grade order by grade desc;
 grade | 总人数 | 男生数 | 女生数 | 性别未知 
-------+--------+--------+--------+----------
     6 |      4 |      4 |      4 |        4
     5 |      2 |      2 |      2 |        2
     4 |      4 |      4 |      4 |        4

看完上边的例子,说说count(1) 与 count(列或表达式)时的差别,count(1)会全部列都计算其内,count(列或表达式)不会将null计入其中。
sum也是如此,例如有某表字段F有三列,A,B,C
三列都不为空,则sum(A+B+C)
假如其中有空值,比如说是A, 则 sum会忽略A值,最终结果为 sum(B+C)

最终结论:只要条件合理,count case when 与 sum的结果是一致的。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值