1.需求
现在需要统计每个id出现指定几种scode的次数;
例:需要统计每个id出现12001,13001,15001出现的次数:
源数据表如下(table_01):
id | scode |
---|---|
001 | 12001 |
001 | 15001 |
002 | 13001 |
002 | 12001 |
001 | 12001 |
001 | 13001 |
002 | 13001 |
003 | 18001 |
需要产出的表如下(table_01):
id | cnt_12001 | cnt_13001 | cnt_15001 |
---|---|---|---|
001 | 2 | 0 | 1 |
002 | 1 | 2 | 1 |
2.实现方式
首先肯定会想到一种"原生态"的方式:
-
SELECT id
-
,COUNT(1) cnt_12001
-
FROM table_01
-
WHERE scode = 12001
-
GROUP BY id;
先将每种scode的数据选出来,一个一个的统计次数,然后再把这几种scode的统计结果按照id join起来,形成一张完整的表.这种方式适用需要统计的scode的种类少的情况,当scode种类有五六七八种的时候这种一个一个去join的方式会让人抓狂的,所以就需要下面这种方式.
-
SELECT id
-
,sum(CASE WHEN scode=12001 THEN 1 ELSE 0 END) cnt_12001
-
,sum(CASE WHEN scode=13001 THEN 1 ELSE 0 END) cnt_13001
-
,sum(CASE WHEN scode=15001 THEN 1 ELSE 0 END) cnt_15001
-
FROM table_01
-
WHERE scode IN (12001,13001,15001 )
-
GROUP BY id;
这种方式可以将条件下载sum里面,判断好以后再加和,实现了带条件count的功能.
得到table_2:
id | cnt_12001 | cnt_13001 | cnt_15001 |
---|---|---|---|
001 | 2 | 0 | 1 |
002 | 1 | 2 | 1 |
到这里又有人说了,这样的话where条件里面是不是不用写scode的条件了呢?
当where条件中不写scode的条件时,这时id为003的这条信息才会出现
id | cnt_12001 | cnt_13001 | cnt_15001 |
---|---|---|---|
001 | 2 | 0 | 1 |
002 | 1 | 2 | 1 |
003 | 0 | 0 | 0 |
因为003没有这几种scode的数据,所以id003的统计结果全为0;
当然这里sum换成count也行,那么在count中需要填入什么条件呢?
我们评论见!