本篇文章介绍如何使用HAVING取数据集合的众数和中位数

参考《SQL进阶教程》

1. 创建测试表及测试数据

CREATE TABLE graduates (name varchar(255),income number(10)
);INSERT INTO graduates VALUES ('桑普森', '400000');
INSERT INTO graduates VALUES ('迈克', '30000');
INSERT INTO graduates VALUES ('怀特', '20000');
INSERT INTO graduates VALUES ('阿诺德', '20000');
INSERT INTO graduates VALUES ('史密斯', '20000');
INSERT INTO graduates VALUES ('劳伦斯', '15000');
INSERT INTO graduates VALUES ('哈德逊', '15000');
INSERT INTO graduates VALUES ('肯特', '10000');
INSERT INTO graduates VALUES ('贝克', '10000');
INSERT INTO graduates VALUES ('斯科特', '10000');COMMIT;

2. 取income众数

select income,count(*) cnt
from graduates
group by income
having count(*) = (
select max(cnt) from (select count(*) cnt from graduates group by income) tmp
);

需求分析:

例子中要取income的众数,也就是出现次数最多income.思路如下:

(1)确定众数值出现的次数

(2)根据次数获取众数对应的值

(3)整合SQL

2.1 确定众数值出现的次数
SQL> select max(cnt) from (select count(*) cnt from graduates group by income) tmp;MAX(CNT)
----------3
2.2 根据次数获取众数对应的值
SQL> select income,count(*) cnt 2  from graduates3  group by income4  having count(*) = 3;INCOME        CNT
---------- ----------10000          320000          3
2.3 整合SQL
SQL> select income,count(*) cnt 2  from graduates3  group by income4  having count(*) = (5  select max(cnt) from (select count(*) cnt from graduates group by income) tmp6  );INCOME        CNT
---------- ----------10000          320000          3

3. 取income中位数

select AVG(tmp.income)
from (
select T1.income from graduates T1,graduates T2
group by T1.income
having sum(case when T1.income >= T2.income then 1 else 0 end) >= count(*)/2
and sum(case when T1.income <= T2.income then 1 else 0 end) >= count(*)/2
) tmp;

需求分析:

数学中取中位数:

把集合中的元素按升序排列后,取位于中间的元素. 如果元素个数为偶数,则取中间两个元素的平均值.

SQL实现思路: 把集合元素按大小排序后,分为上下两部分,然后取两部分交集,再取平均值

实现步骤:

(1) 假设有相同的两个集合T1,T2,取两集合的笛卡尔积

(2) 如果T1中income 大于 T2中的income,则flag记为 1,小于则记为 0

(3) 区分上下部分

  • 对T1中每个income对应的flag取和sum_flag.

  • 对于T1中每一个income,如果sum_flag ≥ count(flag)/2,则判断此income值属于上半部分(较大部分),否则 属于下半部分(较小部分)

    • count(flag)/2 有什么用

      count(flag)/2表示T1集合的中间位置

    • 为什么是≥,而不是>

      因为当元素个数为奇数时使用">"没有问题,但当元素个数为偶数时,上下部分没有交集,所以使用 “≥”.

(4) 取上下部分的交集,并取平均值

(5) 整合SQL

3.1 假设有相同的两个集合T1,T2,取两集合的笛卡尔积
SQL> select t1.income,t2.income from GRADUATES t1,GRADUATES t2;INCOME     INCOME
---------- ----------400000     400000400000      30000400000      20000400000      20000400000      20000400000      15000400000      15000400000      10000400000      10000400000      1000030000     400000中间略...
100 rows selected.
3.2 如果T1中income 大于等于 T2中的income,则flag记为 1,小于则记为 0
SQL> select 2  t1.income AS income_t1,3  t2.income AS income_t2,4  (CASE WHEN t1.income >= t2.income THEN 1 ELSE 0 END) AS flag5  from GRADUATES t1,GRADUATES t2;取部分输出结果...
20000     400000          0
20000      30000          0
20000      20000          1
20000      20000          1
20000      20000          1
20000      15000          1
20000      15000          1
20000      10000          1
20000      10000          1
20000      10000          1
...
3.3 区分上下部分
  • 上半部分

    SQL> select t1.income AS income2  from GRADUATES t1,GRADUATES t23  GROUP BY t1.income4  HAVING SUM(CASE WHEN t1.income >= t2.income THEN 1 ELSE 0 END) >= COUNT(*)/2;INCOME
    ----------300001500040000020000
    
  • 下半部分

    
    SQL> select t1.income AS income2  from GRADUATES t1,GRADUATES t23  GROUP BY t1.income4  HAVING SUM(CASE WHEN t1.income <= t2.income THEN 1 ELSE 0 END) >= COUNT(*)/2;INCOME
    ----------100001500020000
    
3.4 取上下部分的交集,并取平均值
SQL> SELECT avg(tmp.income) FROM (2  select t1.income AS income3  from GRADUATES t1,GRADUATES t24  GROUP BY t1.income5  HAVING SUM(CASE WHEN t1.income >= t2.income THEN 1 ELSE 0 END) >= COUNT(*)/26  INTERSECT7  select t1.income AS income8  from GRADUATES t1,GRADUATES t29  GROUP BY t1.income10  HAVING SUM(CASE WHEN t1.income <= t2.income THEN 1 ELSE 0 END) >= COUNT(*)/211  ) tmp;AVG(TMP.INCOME)
---------------17500
3.5 整合SQL
SQL> select AVG(tmp.income)2  from (3  select T1.income from graduates T1,graduates T24  group by T1.income5  having sum(case when T1.income >= T2.income then 1 else 0 end) >= count(*)/26  and sum(case when T1.income <= T2.income then 1 else 0 end) >= count(*)/27  ) tmp;AVG(TMP.INCOME)
---------------17500

【SQL】利用HAVING取众数和中位数相关推荐

  1. 一文搞懂SQL-计算众数、中位数

    众数的概念 众数作为统计学中重要的概念,它指在群体出现次数最多的值,在下面这张表中,众数是10000和20000这两个值. name income 辛普森 400000 迈克 30000 怀特 200 ...

  2. 华为机试:查找众数及中位数

    一道华为od机试的简单题. 查找众数及中位数 题目描述 1.众数是指一组数据中出现次数量多的那个数,众数可以是多个 2.中位数是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最 ...

  3. 华为OD机试 -众数和中位数(Java) | 机试题+算法思路+考点+代码解析 【2023】

    众数和中位数 题目 众数是指一组数据中出现次数多的数 众数可以是多个 中位数是指把一组数据从小到大排列,最中间的那个数, 如果这组数据的个数是奇数,那最中间那个就是中位数 如果这组数据的个数为偶数,那 ...

  4. 整数序列中的众数和中位数

    描述 输入无符号整数序列(不多于500个整数,每个整数不大于150),计算序列的众数和中位数. 众数是指出现次数最多的那个数:如果有多个数出现的次数都达到最多,则取最先出现的数为众数:如果所有的数都相 ...

  5. Javascript 计算众数和中位数的代码

    先介绍一下众数和中位数: 众数: 一般来说,一组数据中,du出现次数最多的数就叫这组数据的众数. 例如:zhi2,3,3,3,4,5的众数是dao3. 中位数: 把一组数据按从小到大的数序排列,在中间 ...

  6. HW算法题:查找众数及中位数

    /** 查找众数及中位数* 众数是指一组数据中出现次数量多的那个数,众数可以是多个, 中位数是指把一组数据从小到大排列,最中间的那个数* 如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据 ...

  7. 算法:查找众数及中位数

    查找众数及中位数 1.众数是指一组数据中出现次数量多的那个数,众数可以是多个 2.中位数是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数 ...

  8. 【华为OD机试真题 JAVA】查找众数及中位数

    JS版:[华为OD机试真题 JS]查找众数及中位数 标题:查找众数及中位数 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限 1.众数是指一组数据中出现次数量多的那个数,众数可以是 ...

  9. 【华为OD机试真题 JS】查找众数及中位数

    标题:查找众数及中位数 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限 1.众数是指一组数据中出现次数量多的那个数,众数可以是多个 2.中位数是指把一组数据从小到大排列,最中间的 ...

最新文章

  1. 再度剖析AD账户新旧密码同时可用的问题
  2. Docker学习之路 用commit命令创建镜像
  3. cocoJS配置文件:project.json
  4. VTK:图表之BreadthFirstDistance
  5. 传统公司部署OpenStack(t版)简易介绍(一)——环境部署
  6. 远程连接本地mongodb 数据库
  7. 项目管理平台(总结篇二)
  8. 容器编排技术 -- 使用Minikube 部署 Kubernetes 集群
  9. python3 redis长链接超时_Python3 连接Redis字符串和字节问题探究
  10. 达梦数据库存储过程调用
  11. css hot loader,怎么针对依赖包的css 单独写一条loader的规则,不开启 css modules
  12. 硅谷大佬们屡次推荐的10本书,你看过几本?
  13. 从安装双系统到TurtleBot3入门教程
  14. Raucous Rockers
  15. oBlog 4.0 正式版 2006-09-06
  16. 案例:世界500强如何打造汽车后市场智慧门店
  17. 让女人无法抗拒的30句表白【实用】
  18. 加密文件的识别和破解工具,电子数据勘察取证实验室建设项目-掘密
  19. Wired特写: 网络让她陷入「匿名虐待」的世界,这是一场关于数据和不信任的无休止暴力
  20. 匠心造就可靠,协同铸就未来

热门文章

  1. leetcode 链表1
  2. C8051汇编语言递归,基于C8051F310单片机的LED灯控制器汇编语言程序调试
  3. 压缩 质量不变_来了!业内首个HEIF图像高质量压缩FPGA加速方案
  4. 可以储存照片的字段类型是_在sql server中,储存图片的数据类型是什么呀?
  5. 【iOS-cocos2d-X 游戏开发之八】使用Lua脚本进行游戏开发(基础篇)
  6. Eclipse中java文件头注释格式设置
  7. Windows Server 2012 R2 VDI系列(八)—发布RemoteDesktop
  8. Android 高级控件ListView用法
  9. spring boot 配置
  10. 微信公众号 分享接口 签名通过 分享无效果(JSSDK自定义分享接口的策略调整)...