目录

  • sql实现寻找中位数
    • 思路1
    • 算法
      • case
      • sign():
    • 思路二:排序后再找中位数

sql实现寻找中位数

思路1

对于一个 奇数 长度数组中的 中位数,大于这个数的数值个数等于小于这个数的数值个数。

算法

根据上述的定义,我们来找一下 [1, 3, 2] 中的中位数。首先 1 不是中位数,因为这个数组有三个元素,却有两个元素 (3,2) 大于 1。3 也不是中位数,因为有两个元素小于 3。对于最后一个 2 来说,大于 2 和 小于 2 的元素数量是相等的,因此 2 是当前数组的中位数。

当数组长度为 偶数,且元素唯一时,中位数等于排序后 中间两个数 的平均值。对这两个数来说,大于当前数的数值个数跟小于当前数的数值个数绝对值之差为 1,恰好等于这个数出现的频率

总的来说,不管是数组长度是奇是偶,也不管元素是不是唯一,中位数出现的频率一定大于等于大于它的数和小于它的数的绝对值之差。这个规律是这道题的关键,可以通过下面这个搜索条件来过滤。

--架构
Create table If Not Exists Employee (Id int, Company varchar(255), Salary int)
Truncate table Employee
insert into Employee (Id, Company, Salary) values ('1', 'A', '2341')
insert into Employee (Id, Company, Salary) values ('2', 'A', '341')
insert into Employee (Id, Company, Salary) values ('3', 'A', '15')
insert into Employee (Id, Company, Salary) values ('4', 'A', '15314')
insert into Employee (Id, Company, Salary) values ('5', 'A', '451')
insert into Employee (Id, Company, Salary) values ('6', 'A', '513')
insert into Employee (Id, Company, Salary) values ('7', 'B', '15')
insert into Employee (Id, Company, Salary) values ('8', 'B', '13')
insert into Employee (Id, Company, Salary) values ('9', 'B', '1154')
insert into Employee (Id, Company, Salary) values ('10', 'B', '1345')
insert into Employee (Id, Company, Salary) values ('11', 'B', '1221')
insert into Employee (Id, Company, Salary) values ('12', 'B', '234')
insert into Employee (Id, Company, Salary) values ('13', 'C', '2345')
insert into Employee (Id, Company, Salary) values ('14', 'C', '2645')
insert into Employee (Id, Company, Salary) values ('15', 'C', '2645')
insert into Employee (Id, Company, Salary) values ('16', 'C', '2652')
insert into Employee (Id, Company, Salary) values ('17', 'C', '65')
SELECTEmployee.Id, Employee.Company, Employee.Salary
FROMEmployee,Employee alias
WHEREEmployee.Company = alias.Company
GROUP BY Employee.Company , Employee.Salary
HAVING SUM(CASEWHEN Employee.Salary = alias.Salary THEN 1ELSE 0
END) >= ABS(SUM(SIGN(Employee.Salary - alias.Salary)))
ORDER BY Employee.Id;
--alias是别名

1.运用CASE表达式,非等值自连接和HAVING子句来找中位数
2.通过 WHERE e1.Company = e2.Company 进行分组
3.最后通过GROUP BY 去重

--更好理解一些:
select Id, Company, Salary
from Employee
where Id in (select e1.Id
from Employee e1, Employee e2
WHERE e1.Company = e2.Company
GROUP BY e1.Id
HAVING SUM(CASE WHEN e1.Salary >= e2.Salary THEN 1 ELSE 0 END) >= COUNT(*)/2 AND SUM(CASE WHEN e1.Salary <= e2.Salary THEN 1 ELSE 0 END) >= COUNT(*)/2)
GROUP BY Company, Salary
ORDER BY Company

case

The CASE statement goes through conditions and returns a value when the first condition is met (like an IF-THEN-ELSE statement). So, once a condition is true, it will stop reading and return the result. If no conditions are true, it returns the value in the ELSE clause.If there is no ELSE part and no conditions are true, it returns NULL.

--用例
CASEWHEN condition1 THEN result1WHEN condition2 THEN result2WHEN conditionN THEN resultNELSE result
END;

sign():

这里是引用

ps:注意:在 MySQL 5.6 中,这个代码是可以运行的,但如果你用的是 MySQL 5.7+,就需要在 SELECT 语句中 把 Employee.id 改成 ANY_VALUE(Employee.Id)。

思路二:排序后再找中位数

根据 salary 排序记录,利用会话变量计算排名。由于不需要级联表,这个方法要比方法一更高效。

SELECT Id, Company, Salary
FROM(SELECT e.Id,e.Salary,e.Company,IF(@prev = e.Company, @Rank:=@Rank + 1, @Rank:=1) AS rank,@prev:=e.CompanyFROMEmployee e, (SELECT @Rank:=0, @prev:=0) AS tempORDER BY e.Company , e.Salary , e.Id) RankingINNER JOIN(SELECT COUNT(*) AS totalcount, Company AS nameFROMEmployee e2GROUP BY e2.Company) companycount ON companycount.name = Ranking.Company
WHERERank = FLOOR((totalcount + 1) / 2)OR Rank = FLOOR((totalcount + 2) / 2)
;

自定义变量

sql实现寻找中位数(使用sign、case、自定义变量等)相关推荐

  1. 2018六校联合周赛上学期第一场-我来爆零啦 寻找中位数 kth

    题目链接 寻找中位数 TimeLimit:1000MS  MemoryLimit:128MB 64-bit integer IO format:%lld Problem Description 这题温 ...

  2. seaborn可视化displot绘制直方图(histogram)并通过axvline函数在直方图中添加中位数(median)竖线(自定义中位数竖线的线条形式)

    seaborn可视化displot绘制直方图(histogram)并通过axvline函数在直方图中添加中位数(median)竖线(自定义中位数竖线的线条形式) 目录

  3. 百练OJ:2388:寻找中位数

    题目连接:2388:寻找中位数 描述 在N(1<=N<10,000且N为奇数)个数中,找到中位数. 输入第1行:N 第2至N+1行:每行是一个整数输出第一行:中位数样例输入 5 2 4 1 ...

  4. sql语句中case_SQL中的CASE语句

    sql语句中case The case statement in SQL returns a value on a specified condition. We can use a Case sta ...

  5. C语言——选择控制结构 寻找中位数v1.0编写一个函数返回三个整数中的中间数。函数原型:int mid(int a, int b, int c);功能是返回a,b,c三数中大小位于中间的一个数。

    寻找中位数v1.0 编写一个函数返回三个整数中的中间数. 函数原型:int mid(int a, int b, int c); 功能是返回a,b,c三数中大小位于中间的一个数. 程序运行结果示例1: ...

  6. 寻找中位数(利用快速排序来寻找中位数)

    文章目录 寻找中位数(利用快速排序来寻找中位数) 程序设计 程序分析 寻找中位数(利用快速排序来寻找中位数) [问题描述] FJ is surveying his herd to find the m ...

  7. leetCode每日一题 寻找中位数

    题目 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2. 请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 ...

  8. 【SQL数据库基础08】变量--系统变量:全局、会话、自定义变量

    文章目录 一.系统变量 1.查看所有系统变量 2.查看满足条件的部分系统变量 3.查看指定的系统变量的值 4.为某个系统变量赋值 1.1 全局变量 ①查看所有全局变量 ②查看满足条件的部分系统变量 ③ ...

  9. mysql自定义变量比较大小_MySQL 自定义变量@ 常用案例

    以下文章来源于SQL开发与优化 大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 很久没有写文章,最近碰到了一个非常有意思的Oracle SQL 案例, 这个案例,我用了一些窗口函数来解决的,后 ...

最新文章

  1. 原型模式(Prototype)
  2. python调用r语言_【Python调用第三方R包】【环境变量设置】Python 通过rpy2调用 R语言...
  3. C#之委托的个人理解
  4. 窗口句柄、窗口类对象的关系
  5. numpy创建zeros数组时报错TypeError: Cannot interpret ‘8‘ as a data type
  6. MFC和GTK的区别
  7. mfc socket onreceive函数不被调用_不报错地调用空指针类的成员函数
  8. js 中的 __proto__
  9. [转载] python pandas.read_csv读取大文件
  10. 计算机怎么剪切音乐然后合在一起,电脑怎么剪辑合并音乐
  11. C#数据库编程实战经典
  12. 用 Python 修改微信(支付宝)运动步数,轻松 TOP1
  13. 技术人员如何创业(4)---打造超强执行力团队
  14. 数字化转型的必要性和意义
  15. python的快捷键是什么意思_Python基础知识—快捷键
  16. Windows的快捷方式、符号链接、目录联接、硬链接的区别
  17. 关于Android 4.4(华为)调用系统相机问题
  18. 设计模式 —— Builder 模式
  19. C. Ehab and Path-etic MEXs(思维+构造)
  20. 浅析企业级应用系统--ERP

热门文章

  1. mysql filck_顺序全局id生成方案-flickr(转载)
  2. 如何快速的入门git实现版本控制
  3. 三角形旋转c语言程序,c语言图形,请高手修改,效果是一个三角形绕一点旋转一周...
  4. java mysql 动态sql_Java下拼接运行动态SQL语句
  5. PHP删除排序数组中的重复项,每日一道算法:删除排序数组中的重复项
  6. Python -- reload 函数
  7. 【BZOJ1037】【codevs1410】生日聚会,DP
  8. 【BZOJ2226】LCM SUM,数论之一维LCM(莫比乌斯反演)
  9. 【BZOJ1009】【codevs2325】GT考试,kmp+矩阵加速DP
  10. mysql 5.7自定义安装路径_Mysql5.7.18版本(二进制包安装)自定义安装路径教程详解...