select
(select distinct salary from Employee order by salary desc limit 1 offset 1)
as SecondHighestSalary;
这样的写法就类似于
sql复制代码
select 1+2 as SecondHighestSalary;
不需要有数据来源,因为这个表达式的计算结果已经是一个数据了。
这里只是给数据起一个别名。若是子查询数据为空,那么返回的就是null 而不是空了
总之。在 SQL 中使用子查询而没有 FROM 子句的情况通常是为了计算一个表达式或获取一个基于特定逻辑的单一结果,子查询本身提供了数据来源和处理逻辑,无需再通过 FROM 从物理表中获取数据。但在实际应用中,需要考虑性能和可维护性,避免过度复杂的子查询结构。
解法二(使用 IFNULL 和 LIMIT 子句):
sql复制代码
select ifnull(
(select distinct salary from Employee order by salary desc limit 1,1),null
)
as SecondHighestSalary;
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
declare M INT;
set M = N-1;
RETURN (
select distinct salary from Employee order by salary desc limit M,1
);
END
注意,limit中参数不能写成表达式的形式。也就是不能写成N-1
需要单独定义一个变量 M = N-1
代码解释
这个 SQL 代码创建了一个名为 getNthHighestSalary 的函数,该函数接收一个整数参数 N,用于表示要查找第 N 高的薪水。函数的返回值是一个整数,代表第 N 高的薪水值。
变量声明:
sql复制代码
declare M INT;
变量赋值:
sql复制代码
set M = N-1;
查询语句
sql复制代码
RETURN (
select salary from Employee order by salary desc limit M,1
);
select distinct l1.num as ConsecutiveNums
from Logs l1,Logs l2,Logs l3
where
l1.id = l2.id-1 and
l2.id = l3.id-1 and
l1.num = l2.num and
l2.num = l3.num;
select d.name Department,e.name Employee,e.salary
from Employee e,Department d
where e.departmentId = d.id
and e.salary >=
all (select salary from Employee t where e.departmentId = t.departmentId);
sql复制代码
e.salary >=
all (select salary from Employee t where e.departmentId = t.departmentId);
员工薪资 ≥ 相同部门的薪资。
法二、窗口函数(MAX()+行子查询)
sql复制代码
select d.name AS 'Department',e.name AS 'Employee',Salary
FROM Employee e JOIN Department d ON e.DepartmentId = d.Id
where (e.DepartmentId , Salary) in
(select DepartmentId, MAX(Salary) from Employee
GROUP BY DepartmentId);
where 条件 绑定了部门 id 和 薪资水平 in
查出来的 部门id 和最高的薪资水平。
sql复制代码
select DepartmentId, MAX(Salary) from Employee
GROUP BY DepartmentId;
法三:窗口函数(dense_rank() partition by)(推荐)
sql复制代码
select d.name AS 'Department',e.name AS 'Employee',e.salary Salary
from
(select *,dense_rank() over(partition by departmentId order by salary desc) as erank
from Employee) e ,Department d
where e.departmentId = d.Id
and erank <= 1;
select d.name as Department, e.name as Employee,salary Salary from
(select *, dense_rank()
over(partition by departmentId order by salary desc) as erank
from Employee) e
left join Department d on e.departmentId = d.id
where erank <= 3;
其中
sql复制代码
select *, dense_rank()
over(partition by departmentId order by salary desc) as erank
from Employee;