SQL使用CASE WHEN 行转列为啥会出现NULL值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL使用CASE WHEN 行转列为啥会出现NULL值?相关的知识,希望对你有一定的参考价值。

菜鸟一枚,学习SQL时遇到这样一个问题迟迟摸不到头绪,问题如下:

查询语句:

select avg(总分),
case when 性别='男' then '男生的平均成绩'
when 性别='女' then '女生的平均成绩'
end
from students
GROUP BY 性别

结果集:

(无列名) (无列名)
178 男生的平均成绩
145 女生的平均成绩
--------------------------------------------------------------------------------
行转列后代码:
select --avg(总分),
case when 性别='男' then avg(总分) END AS '男生的平均成绩',
case when 性别='女' then avg(总分) END AS '女生的平均成绩'
from students
GROUP BY 性别

为什么结果集会出现这样的情况:
结果集:

男生的平均成绩 女生的平均成绩
178 NULL
NULL 145

为什么会出现这样的问题,该怎么解决,跪求大侠相助!

因为是男女分别统计,一般不这么用

select --avg(总分),
    avg(case when 性别=\'男\' then 总分 else 0 END) AS \'男生的平均成绩\',
    avg(case when 性别=\'女\' then 总分 else 0 END) AS \'女生的平均成绩\'
from students
--GROUP BY 性别--这个group by去掉

你试试

参考技术A 要注意不能计算男、女的平均成绩时,不能对所有人进行avg:

select avg(总分),
    sum(case when 性别='男' then 总分 else 0 end)/count(case when 性别='男' then 1 else 0 end) 男生的平均成绩,
    sum(case when 性别='女' then 总分 else 0 end)/count(case when 性别='女' then 1 else 0 end) 女生的平均成绩
from students

参考技术B 当case 子句的条件未包括所有的取值情况,会出现null值。

例:select case when a >1 then A,when a=1 then b end
那么当 a< 1 时,语句中未指定取值,则返回 null值。
参考技术C 你这逻辑不对。

select avg(总分) 平均分,
avg(case when 性别='男' then 总分 else 0 END) AS '男生平均成绩',
avg(case when 性别='女' then 总分) else 0 END) AS '女生平均成绩'
from students;
参考技术D 逻辑有问题。
首先你group by 性别,但是字段中却不取性别,虽然不是一定不行,但是这样有可能产生问题的时候因为你忽略了一个字段导致你发现不了。
其次你group by 性别,应该是想按性别来分组显示,但是你又用了case when判断语句,一般来说case when很少用在分组语句中,即使一定要用,也应该配合聚合语句(如sum,count等),你这个语法应该是无法通过的。
正确的语句楼下有写你可以看他的,但是其实写得更有逻辑性:
select 性别,sum(分数)/count(人名) from students
group by 性别
逻辑简单易懂才不容易出错

SQL中怎么将行转成列?

文章目录

天天这需求就神奇!!!!

SQL中怎么将行转成列?

我们以MySQL数据库为例,来说明行转列的实现方式。
首先,假设我们有一张分数表(tb_score),表中的数据如下图:


然后,我们再来看一下转换之后需要得到的结果,如下图:


可以看出,这里行转列是将原来的subject字段的多行内容选出来,作为结果集中的不同列,并根据userid进行分组显示对应的score。通常,我们有两种方式来实现这种转换。

1. 使用 CASE…WHEN…THEN 语句实现行转列,参考如下代码:

SELECT userid, 
SUM(CASE `subject` WHEN '语文' THEN score ELSE 0 END) as '语文', 
SUM(CASE `subject` WHEN '数学' THEN score ELSE 0 END) as '数学', 
SUM(CASE `subject` WHEN '英语' THEN score ELSE 0 END) as '英语', 
SUM(CASE `subject` WHEN '政治' THEN score ELSE 0 END) as '政治' 
FROM tb_score 
GROUP BY userid

注意,SUM() 是为了能够使用GROUP BY根据userid进行分组,因为每一个userid对应的
subject="语文"的记录只有一条,所以SUM() 的值就等于对应那一条记录的score的值。假如userid ='001' and subject='语文' 的记录有两条,则此时SUM() 的值将会是这两条记录的和,同理,使用Max()的值将会是这两条记录里面值最大的一个。但是正常情况下,一个user对应一个subject只有一个分数,因此可以使用SUM()、MAX()、MIN()、AVG()等聚合函数都可以达到行转列的效果。

2. 使用 IF() 函数实现行转列,参考如下代码:

SELECT userid, 
SUM(IF(`subject`='语文',score,0)) as '语文', 
SUM(IF(`subject`='数学',score,0)) as '数学', 
SUM(IF(`subject`='英语',score,0)) as '英语', 
SUM(IF(`subject`='政治',score,0)) as '政治' 
FROM tb_score 
GROUP BY userid

注意, IF(subject='语文',score,0) 作为条件,即对所有subject='语文’的记录的score字段进行SUM()、MAX()、MIN()、AVG()操作,如果score没有值则默认为0。

以上是关于SQL使用CASE WHEN 行转列为啥会出现NULL值?的主要内容,如果未能解决你的问题,请参考以下文章

行转列与CASE.....WHEN...

MySQL的CASE WHEN用法

sqlserver日期行转列的问题

MySQL -- 行转列 -- GROUP_CONCAT -- MAX(CASE WHEN THEN)

SQL中怎么将行转成列?

SQL中怎么将行转成列?