- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
今天有同事问我一道关于数据库SQL的面试题,我刚开始随便给了一个思路,后来思索发现这个思路有漏洞,于是总结下来,仅供参考.
问题: 薪水表中是员工薪水的基本信息,包括雇员编号,和薪水,查询除去最高、最低薪水后的平均薪水.
CREATE TABLE `salaries` ( `emp_no` int NOT NULL , `salary` int NOT NULL ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
测试数据如下:
INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10003 , 6000 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10004 , 6000 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10001 , 6000 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10006 , 6100 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10005 , 6900 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 10008 , 7100 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100010 , 7400 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100013 , 7500 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100014 , 7500 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100015 , 7688 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100018 , 8000 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100020 , 8100 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100028 , 8200 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100026 , 8400 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100035 , 8500 ); INSERT INTO `salaries`(`emp_no`, `salary`) VALUES ( 100038 , 8500 );
思路1、最容易想到的方法,就是查询到薪水的最大值和最小值。然后从薪水中排除掉这两个,计算平均值即可.
select avg (salary) from salaries where salary not in ( ( select min (salary) from salaries), ( select max (salary) from salaries) ) ;
。
思路2、使用开窗函数Max() Over() 和 Min() Over() 求出最大值,然后排除掉这两个,再计算平均值.
select avg (salary) from ( select emp_no,salary, min (salary) over () min_sal, max (salary) over () max_sal from salaries ) x where salary not in (min_sal,max_sal) ;
。
思路3 、直接使用数学方法,平均值 = (求和-最大值-最小值)/ (总个数-2) 。
select (sum(salary)-min(salary)-max(salary))/(count(*)-2
)
from salaries ;
。
思路4、使用一次row_number() over 窗口函数和count() over 函数,count窗口函数统计表中所有记录数,使用row_number窗口函数按照薪水升序排列,排序结果 = 1 即为最小值,排序结果 = count出的结果 即为最大值。 。
select avg (salary) from ( select emp_no, salary, count ( * ) over () num , row_number() over ( order by salary asc ) rn from salaries ) T where rn <> 1 and rn <> num ;
说明:
count ( * ) over () 求总计数, count ( * ) over ( order by A...) 递加求计数, count ( * ) over (partition by A...) 分组求计数, count ( * ) over (partition by A... order by b...) 分组递加求计数
查询看下这四个统计结果 。
。
思路5、使用两次row_number() over 窗口函数,一个按照薪水升序,一个按照薪水降序,过滤掉第一个即去掉最大值和最小值.
select avg (salary) from ( select emp_no, salary, row_number() over ( order by salary desc ) rn_desc, row_number() over ( order by salary asc ) rn_asc from salaries ) T where rn_desc > 1 and rn_asc > 1 ;
。
总结: 我们在执行这5个SQL语句后,会发现统计出的平均值不一样,原因就在于:薪水表中最高薪水的人和最低薪水的人都不止一个.
前2个思路会将所有最高薪水和最低薪水全部去除,求得平均值。 然而,思路3、4、5都只是去除一个最高薪水和一个最低薪水,然后求平均值。所以才导致计算出的结果不一致.
。
最后此篇关于SQL-去除最大值与最小值求均值的问题的文章就讲到这里了,如果你想了解更多关于SQL-去除最大值与最小值求均值的问题的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!