SQL 第54题

解法一
select
avg(salary)
from salaries
where salary not in (
select
min(salary)
from salaries
where to_date = '9999-01-01'
)
and salary not in (
select
max(salary)
from salaries
where to_date = '9999-01-01'
)
and to_date = '9999-01-01'
#where不能用聚合函数 因此用select 排除最大值和最小值
简单粗暴

解法二 窗口函数
select
avg(salary)
from (
select
*
,row_number() over(order by salary) r1
,row_number() over(order by salary desc) r2
from salaries
where to_date = '9999-01-01'
) a
where a.r1 <>1
and a.r2 <> 1
#把最大值和最小值去掉
解法三 把最大和最小去掉

select
avg(salary)
from (
select
salary
,max(salary) over() s1
,min(salary) over() s2
from salaries
where to_date = "9999-01-01"
) a
where a.salary < a.s1
and a.salary > a.s2

值得注意的点:
一、解法三必须使用窗口函数,因为直接使用max或者min只输出一个观测值,除非使用join将所有观测和max与min连接起来,那样会很麻烦,而窗口函数则直接输出全部值。
二、注意算法运行的顺序,where后面不能使用聚合函数,where在select前运行。
三、“Having”是一个过滤声明,所谓过滤是在查询数据库的结果返回之后进行过滤,即在结果返回之后起作用,并且having后面可以使用“聚合函数”。