SQL 计算众数,需要找出某一列的众数(即在一组数据里出现次数最多的那个数)。例如,希望找出 DEPTNO
等于 20 的部门里员工工资的众数。就如下示例而言,众数为 3000。
SQL 计算众数 问题描述
需要找出某一列的众数(即在一组数据里出现次数最多的那个数)。例如,希望找出 DEPTNO
等于 20 的部门里员工工资的众数。就如下示例而言,众数为 3000。
SQL 计算众数 解决方案
DB2 和 SQL Server
使用窗口函数 DENSE_RANK
对工资值出现的次数进行排序,以帮助我们找到众数。
Oracle
对于 Oracle 8i 来说,可以使用 DB2 的解决方案。如果你使用的是 Oracle 9i 及其后续版本,可以使用聚合函数 MAX
的 KEEP
扩展来找到 SAL
列的众数。注意,如果有多个众数,则 KEEP
解决方案只会保留工资值最高的那个。如果希望看到全部众数,就需要修改该解决方案,或者改用前面的 DB2 解决方案。在本例中,因为 3000 是 DEPTNO
等于 20 的部门里 SAL
列的众数,并且也是 SAL 列的最大值,所以下面的解决方案足以胜任。
MySQL 和 PostgreSQL
使用子查询查找众数。
SQL 计算众数 扩展知识
DB2 和 SQL Server
内嵌视图 X
返回每一个 SAL
值及其出现的次数。内嵌视图 Y
使用窗口函数 DENSE_RANK
(该函数允许出现排名相同的状况)对查询结果进行排序。
查询结果按照每一个 SAL
值的出现次数进行排序,如下所示。
最外层的查询只是简单地筛选出 RNK
等于 1 的行。
Oracle
内嵌视图返回每一个 SAL
值及其出现的次数,如下所示。
然后利用聚合函数 MAX
的 KEEP
扩展找到众数。下面的 KEEP
子句包含 DENSE_RANK
、FIRST
和 ORDER BY CNT DESC
三个部分。
这样做很容易查找众数。KEEP
子句会查看内嵌视图返回的 CNT
值,并决定哪一个 SAL
值会被 MAX
函数返回。按照从右向左的执行顺序,所有的 CNT
值先按照降序排列,然后执行 DENSE_RANK
函数,并保留排在第一位的 CNT
值。仔细观察内嵌视图查询结果,可以发现 3000 对应的 CNT
是 2,在查询结果中是最大的。MAX(SAL)
的返回值是最大的 SAL
值,而且其对应的 CNT
值也是最大的,本例中是 3000。