MySQL去重计数,如果条件唯一

34

我试图构建一个查询,告诉我在给定数据集中有多少个不同的女性和男性。每个人都由一个数字“tel”进行标识。同一个“tel”可能会出现多次,但是该“tel”的性别只应计算一次!

7136609221 - 男性
7136609222 - 男性
7136609223 - 女性
7136609228 - 男性
7136609222 - 男性
7136609223 - 女性

这个示例数据集将产生以下结果。
总唯一性别计数:4
总唯一男性计数:3
总唯一女性计数:1

我的尝试查询:

SELECT COUNT(DISTINCT tel, gender) as gender_count, 
       COUNT(DISTINCT tel, gender = 'male') as man_count, 
       SUM(if(gender = 'female', 1, 0)) as woman_count 
FROM example_dataset;

实际上这里有两个尝试。 COUNT(DISTINCT tel, gender = 'male') as man_count 似乎只返回与COUNT(DISTINCT tel, gender)相同的结果 -- 它没有考虑到限定条件。而SUM(if(gender = 'female', 1, 0))统计了所有女性记录,但没有通过DISTINCT tels进行过滤。


1
当你运行这个程序时,你会得到什么样的答案? - James A Mohler
COUNT(DISTINCT tel, gender = 'male') 的结果是 man_count = 4,但实际上应该是 3,因为按照电话号码去重。 - Federico
SUM(if(gender = 'female', 1, 0)) 的结果是 woman_count = 2,这是错误的。应该是 1(每个电话号码唯一)。 - Federico
2个回答

88

这里有一个选项,使用带有DISTINCT的子查询:

SELECT COUNT(*) gender_count,
   SUM(IF(gender='male',1,0)) male_count,
   SUM(IF(gender='female',1,0)) female_count
FROM (
   SELECT DISTINCT tel, gender
   FROM example_dataset
) t

如果您不想使用子查询,这种方法也可以运行:

SELECT COUNT(DISTINCT tel) gender_count,
    COUNT(DISTINCT CASE WHEN gender = 'male' THEN tel END) male_count,  
    COUNT(DISTINCT CASE WHEN gender = 'female' THEN tel END) female_count
FROM example_dataset

6
DISTINCT CASE WHEN gender = 'male' THEN tel END的效果很好,这正是我要找的解决方案。谢谢! - Federico
1
COUNT(DISTINCT CASE WHEN ) 正是我正在寻找的,非常感谢。 - balslev
COUNT(DISTINCT CASE WHEN) 对我有用。非常感谢您。 - Madhura
为什么第二个例子使用 CASE WHEN 而不是 IF() - Stevoisiak

11

还有另一种类似于@segeddes的第二种解决方案的解决方法。

Select COUNT(DISTINCT tel) as gender_count, 
       COUNT(DISTINCT IF(gender = "male", tel, NULL)) as male_count, 
       COUNT(DISTINCT IF(gender = "female", tel, NULL)) as female_count 
FROM example_dataset

说明:

IF(gender = "male", tel, NULL)
如果性别是男性,则上述表达式将返回电话号码,否则将返回空值。
然后我们有...
DISTINCT

它将删除所有重复项

最后

COUNT(DISTINCT IF(gender = "male", tel, NULL))

将计算具有男性性别的行的所有不同出现次数

注意:SQL COUNT函数仅计算具有非NULL值的行的表达式,详细说明请查看 - http://www.mysqltutorial.org/mysql-count/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接