SQL求众数、中值(Having)
程序员文章站
2022-05-29 15:48:17
...
众数
众数:顾名思义就是一组数据中出现次数最多的数。
现有Graduates表:
Graduates表
| name | income |
+--------+--------+
| 桑普森 | 400000 |
| 迈克 | 30000 |
| 怀特 | 20000 |
| 阿诺德 | 20000 |
| 史密斯 | 20000 |
| 劳伦斯 | 15000 |
| 哈德逊 | 15000 |
| 肯特 | 10000 |
| 贝克 | 10000 |
| 斯科特 | 10000 |
查找众数:
select income from graduates group by income
having count(*) >= all(select count(*) from graduates group by income);
注意:当income列有值为null时,用谓词all可能会出现unknown的情况。这种情况是我们不愿意看到的。
可以用极值函数来代替,避免这种情况的发生。
select income from graduates group by income
having count(*) >= max(select count(*) from graduates group by income);
中位数
当平均值不可信时,与众数一样经常被用到的另一个指标是中位数 (median)。它指的是将集合中的元素按升序排列后恰好位于正中间 的元素。如果集合的元素个数为偶数,则取中间两个元素的平均值作 为中位数。
以Graduates表为例求中位数:
--如果中间值有两个,则求平均值。
select avg(income) from (
select g1.income from graduates g1 ,graduates g2
group by g1.income
having
/*我是这样理解的。
count(*)/2可以看作是一组数据排序后的中间的值(组数据长度为偶数则中间值有两个),(sum(case when g1.income >= g2.income then 1 else 0 end) >= count(*)/2)
可以理解为判断该值是不是中间值的之前的最大值,如果是则sum的结果必定是大于等于中间值的。
(sum(case when g1.income <= g2.income then 1 else 0 end) >= count(*)/2)
同样,可以理解为判单g1.incom是不是中间值之后的数据中最小的值,如果大于g1.incom的值超过了count(*)/2,则该值必定小于等于中间值。
两个条件同时满足则就是中间值(数据组中个数为偶数则中间值有两个)。
*/
(sum(case when g1.income >= g2.income then 1 else 0 end) >= count(*)/2)
and
(sum(case when g1.income <= g2.income then 1 else 0 end) >= count(*)/2)
) as t_graduates;
特征函数:用来判断各个元素是否属于满足某个条件的结合。
或则从定义了的集合的角度来说,他是定义函数。
上一篇: DDL语句
下一篇: mysql正则表达式(基础使用)
推荐阅读