员工薪水中位数

题目描述:

预期答案:

解法1

既然是求解中位数,我们首先想到的是根据中位数的定义进行求解:奇数个数字时,中位数是中间的数字;偶数个数字时,中位数中间两个数的均值。本题不进行求解均值,而是将两个中位数全部显示。

根据定义,为了查询中位数,我们需要知道3点信息:

  • 总数是奇数个还是偶数个

  • 待查找数字总数

  • 每个数字的排序编号

前两点信息在MySQL中非常简单,只需简单的count计数即可,而排序编号则需要借助辅助方法。在MySQL8.0以上版本引入了窗口函数后非常容易实现,但以前的版本则仅可通过自定义变量的方式获得排序值。这里如何对员工薪水进行分组排序不再展开

在有了排名和数字总数之后,如何判断是中位数呢?这里计数字总数为N,则

  • N为奇数,中位数排序编号是(N+1)/2=N/2+0.5

  • N为偶数,中位数排序编号是N/2和N/2+1

进一步地,N为奇数和N为偶数是互斥的,求解出的中位数排序编号也是互斥的,也就是说3个排序编号不会同时取得整数,从而可以不加区分的直接判断即可。

查询SQL语句:

SELECT
e1.Id, e1.Company, e1.Salary
FROM
(SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company
FROM Employee, (SELECT @rnk:=0, @pre:=null)init
ORDER by Company, Salary, Id)e1
JOIN
(SELECT Company, count(*) cnt FROM Employee GROUP by Company) e2
using(Company)
WHERE e1.rnk in (cnt/2+0.5, cnt/2, cnt/2+1)

  

查询效率:

解法2

除了根据中位数的排序编号来定位其位置,实际上还可以换种思路但仍然是在其排序编号上做文章:如果一个数是中位数,那么就意味着正序和逆序时其位置是一致的:更严谨的说,奇数个数字是正逆序排序一致,偶数个数字时,两中位数顺序要互换一下,也就是相差为1。进而,我们发现无论数字总数是奇数还是偶数,中位数的正逆排序相差要么为0,要么为1。根据这一性质,我们分别实现正逆两遍排序,然后判断数字的排序编号即可。

查询SQL语句:

SELECT

    e1.Id, e1.Company, e1.Salary

FROM

    (SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company

    FROM Employee, (SELECT @rnk:=0, @pre:=null)init

    ORDER by Company, Salary, Id)e1 

    JOIN 

    (SELECT Id, Company, Salary, @rnk:=if(@pre=Company, @rnk+1, 1) rnk, @pre:=Company

    FROM Employee, (SELECT @rnk:=0, @pre:=null)init

    ORDER by Company, Salary DESC, Id DESC)e2

    on e1.Id=e2.Id

WHERE abs(e1.rnk - e2.rnk)<=1

  

查询效率:

解法3

前2种解法都是根据中位数的定义在数字排序编号上作文章,下面是一个对中位数性质更深的理解(摘抄自官方题解)

根据定义,我们来找一下 [1, 3, 2] 的中位数。首先 1 不是中位数,因为这个数组有三个元素,却有两个元素 (3,2) 大于 1。3 也不是中位数,因为有两个元素小于 3。对于 2 来说,大于 2 和 小于 2 的元素数量是相等的,因此 2 是当前数组的中位数。当数组长度为 偶数,且元素唯一时,中位数等于排序后 中间两个数 的平均值。对这两个数来说,大于当前数的数值个数跟小于当前数的数值个数绝对值之差为 1,恰好等于这个数出现的频率。

结论:不管数组长度是奇是偶,也不管元素是否唯一,中位数出现的频率一定大于等于 大于它的数 和 小于它的数 的绝对值之差。

好吧,力扣的官方题解读起来总是这么生涩。不过细品之下,我们还是可以发现这个结论是对的。【好像说了句废话】

根据中位数的这一性质,可以写出如下查询语句:

SELECT

    e1.Id, e1.Company, e1.Salary

FROM

    Employee e1,

    Employee e2

WHERE

    e1.Company = e2.Company

GROUP BY e1.Company , e1.Salary

HAVING SUM(e1.Salary = e2.Salary) >= ABS(SUM(SIGN(e1.Salary - e2.Salary)))

ORDER BY e1.Id

  

查询效率:

实际上,虽然3种解法均为两表关联,但由于解法3中涉及到相对更为复杂的计算,其效率竟然要比解法1和解法2中低太多。

所以,不妨想想奥卡姆剃刀原理,大道至简、大巧不工、简单之美!

MySQL中如何查询中位数的更多相关文章

  1. mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

  2. 【原创】7. MYSQL++中的查询结果获取(各种Result类型)

    在本节中,我将首先介绍MYSQL++中的查询的几个简单例子用法,然后看一下mysqlpp::Query中的几个与查询相关的方法原型(重点关注返回值),最后对几个关键类型进行解释. 1. MYSQL++ ...

  3. mysql中如何查询最近24小时、top n查询

    MySQL中如何查询最近24小时. where visittime >= NOW() - interval 1 hour; 昨天. where visittime between CURDATE ...

  4. Mysql中分页查询两个方法比较

    mysql中分页查询有两种方式, 一种是使用COUNT(*)的方式,具体代码如下 1 2 3 SELECT COUNT(*) FROM foo WHERE b = 1;   SELECT a FROM ...

  5. mysql中in查询中排序

    mysql中in查询条件的时候,很多时候排序是不规则的,如何按照in里面的条件进行排序呢? mysql中给出了办法,在in后面加order by field,order by field的首个条件是按 ...

  6. mysql 中合并查询结果union用法 or、in与union all 的查询效率

    mysql 中合并查询结果union用法 or.in与union all 的查询效率 (2016-05-09 11:18:23) 转载▼ 标签: mysql union or in 分类: mysql ...

  7. 下面介绍mysql中模糊查询的四种用法:

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

  8. 【面经】面试官:如何以最高的效率从MySQL中随机查询一条记录?

    写在前面 MySQL数据库在互联网行业使用的比较多,有些小伙伴可能会认为MySQL数据库比较小,存储不了很多的数据.其实,这些小伙伴是真的不了解MySQL.MySQL的小不是说使用MySQL存储的数据 ...

  9. MySQL中的查询事务问题

    之前帮同学做个app的后台,使用了MySQL+MyBatis,遇到了一个查询提交的问题,卡了很久,现在有时间了来复盘下 环境情况 假设有学生表: USE test; CREATE TABLE `stu ...

随机推荐

  1. python自动化运维之CMDB篇-大米哥

    python自动化运维之CMDB篇 视频地址:复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1Oj_sglTi2P1CMjfMkYKwCQ  ...

  2. Linux运维博客大全

    系统 U盘安装Linux详细步骤_hanxh7的博客-CSDN博客_u盘安装linux 使用U盘安装linux系统 - lwenhao - OSCHINA 各厂商服务器存储默认管理口登录信息(默认IP ...

  3. C# wpf window

    使用vs2017 新建wpf 项目 MainWindow 被定义为partial,是因为他要和xaml的一些属性组合在一起,然后再运行起来,这正是 InitailizeCompoent 这个函数要干的 ...

  4. Laravel Homestead 安装 使用教程详解!

    1 Laravel Homestead 1 安装: 1 下载: http://www.vagrantup.com/downloads.html 1 配置: 1 1 测试: 1 1 ********** ...

  5. JavaScript string repeat methods All In One

    JavaScript string repeat methods All In One There are many ways in the ES-Next ways repeat ES2015 / ...

  6. LeetCode 最大收益的分配工作

    LeetCode 最大收益的分配工作 工作安排 现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工 ...

  7. Xcode show whitespace

    Xcode show whitespace Xcode 11.5 how to config Xcode show whitespace 如何配置 Xcode 显示空白字符 Editor -> ...

  8. Typescript & classes & public shorthand

    classes & public shorthand Also of note, the use of public on arguments to the constructor is a ...

  9. NGK Global伦敦路演:“区块链+能源”必将推动世界性能源革命

    随着区块链技术的发展和应用的不断完善深入,市场的热情也开始活跃高涨,在万众期待下,NGK Global在英国伦敦的路演于7月25日圆满举办. 此次伦敦路演会议中众多行业精英,各社区代表.星盟投资公司资 ...

  10. 2021-02:Teams开发平台更新概述

    作为2021年工作计划的一部分,我会在每月的第三个星期五发布Teams开发平台的更新报告,给大家整理和讲解最新的平台功能,以及特色场景.这是第一篇文章,我会挑选截至到2月份一些重要的更新,以后每月的更 ...