目录
方法一:sum + case when
方法二:sum + if
方法三:pivot
现在有一张表class_gender,内容如下:
class | gender |
一年级 | 女 |
一年级 | 女 |
一年级 | 男 |
一年级 | 男 |
二年级 | 女 |
二年级 | 女 |
二年级 | 男 |
现在我们要根据上表,统计得到下面的内容,该如何操作呢?
class | 男 | 女 |
一年级 | 2 | 2 |
二年级 | 1 | 2 |
如果用groupby去统计每个年级的男女个数,那么得到的样式如下:
select class,
gender,
count(1) as count
from class_ gender1
group by class , gender
我们需要在这个基础上实现类似python中的unstack的功能,把gender列unstack到列中,那么SQL中怎么实现呢?
方法一:sum + case when
select class ,
sum(case when gender= '男'then 1 else 0 end) 男,
sum(case when gender= '女'then 1 else 0 end)女
from class_ gender1
group by class
方法二:sum + if
select class,
sum(if (gender='男', 1 , 0))男,
sum(if (gender='女', 1 , 0))女
from class_ gender1
group by class
方法三:pivot
这个是类似于stack unstack的方法, 但是我的电脑上总报错,不知道是不是不支持,以后再详细介绍。
先放一个具体的实例供参考:
SELECT [星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日]
FROM WEEK_INCOME
PIVOT
(
SUM(INCOME) for [week] in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])
)TBL--别名一定要写
第一步:
SUM(INCOME) for [week] in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])
这里是PIVOT第一步骤,也是核心的地方,进行行转列操作。
- 聚合函数SUM表示你需要怎样处理转换后的列的值,是总和(sum),还是平均(avg)还是min,max等等。
- 后面的for [week] in([星期一],[星期二]...)中 for [week]就是说将week列的值分别转换成一个个列,也就是“以值变列”。但是需要转换成列的值有可能有很多,我们只想取其中几个值转换成列,那么怎样取呢?就是在in里面了(注意,in里面是原来week列的值)。
- 总的来说,这句代码如果直译出来,就是说:将列[week]值为"星期一","星期二","星期三","星期四","星期五","星期六","星期日"分别转换成列,这些列的值取income的总和。
第二步:
FROM WEEK_INCOME
这里也可以是一个select子查询,但为子查询时候要指定别名,否则语法错误
第三步:
SELECT [星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日]
选择行转列后的结果集的列,这里也可以用 " * " 表示选择所有列,也可以只选择某些列