MySQL统计一个列中不同值的数量

需求: 我们存在一个用户来源表,用来标记用户从哪个渠道注册进来。

其中 origin 是用户来源,其中的值有 iPhone 、Android 、Web 三种,现在需要分别统计由这三种渠道注册的用户数量。

解决方案1

1
2
3
SELECT count(*) 
FROM user_operation_log
WHERE origin = 'iPhone';
1
2
3
SELECT count(*) 
FROM user_operation_log
WHERE origin = 'Android';
1
2
3
SELECT count(*) 
FROM user_operation_log
WHERE origin = 'Web';

缺点是有多少条件就需要查询多少次,比较繁琐.

解决方案2

我们知道 count 不仅可以用来统计行数,也能统计列值的数量,例如:

统计 user_operation_log 有多少行:
SELECT count(*) FROM user_operation_log

统计 origin 这列值不为 NULL 的数量:
SELECT count(origin) FROM user_operation_log

所以我们可以利用这个特性来实现上面的需求

第一种写法(用 count 实现)

1
2
3
4
5
SELECT 
count(origin = 'iPhone' OR NULL) AS iPhone,
count(origin = 'Android' OR NULL) AS Android,
count(origin = 'Web' OR NULL) AS Web
FROM user_operation_log;

第二种写法(用 sum 实现)

1
2
3
4
5
SELECT 
sum(if(origin = 'iPhone', 1, 0)) AS iPhone,
sum(if(origin = 'Android', 1, 0)) AS Android,
sum(if(origin = 'Web', 1, 0)) AS Web
FROM user_operation_log;
1
2
3
4
5
SELECT 
sum(origin = 'iPhone') AS iPhone,
sum(origin = 'Android') AS Android,
sum(origin = 'Web') AS Web
FROM user_operation_log;

最后一种(最优,需要看是否要统计所有类型的)

1
SELECT origin,count(*) num FROM user_operation_log GROUP BY origin;