SQL技术需求:判断员工薪资是否按ID顺序严格降序,返回布尔值
问题描述
编写SQL查询,判断员工表中每一行的薪资是否严格大于其下方所有行的薪资:若所有行都满足该条件则返回true,否则返回false。
示例1(符合条件,返回true)
ID Salary 1 90 2 78 3 68 4 67 5 62
所有员工薪资按ID顺序依次递减,每一行薪资都大于下方所有行,因此返回
true。
示例2(不符合条件,返回false)
ID Salary 1 90 2 78 3 68 4 97 5 62
第3行薪资68小于第4行的97,不满足“每一行薪资大于下方所有行”的要求,因此返回
false。
解决方案
以下提供三种通用的实现思路,适配多数主流SQL数据库:
方法1:窗口函数对比后续最大薪资
利用窗口函数计算当前行之后所有行的最高薪资,检查是否存在当前薪资不大于后续最高薪资的情况:
SELECT CASE WHEN EXISTS ( SELECT 1 FROM ( SELECT Salary, MAX(Salary) OVER (ORDER BY ID ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS next_max_salary FROM employees ) t WHERE Salary <= next_max_salary ) THEN 'false' ELSE 'true' END AS is_strictly_descending;
逻辑说明:
MAX(Salary) OVER (...):按ID顺序,计算当前行之后所有行的最高薪资。- 若存在任意一行薪资≤后续最高薪资,说明不满足条件,返回
false;反之返回true。
方法2:对比原表与降序排序结果
将原表按ID顺序的薪资序列,与按薪资降序排序的序列对比,若完全一致则返回true:
-- 注:不同数据库字符串拼接函数有差异,以下为PostgreSQL示例 SELECT CASE WHEN ( SELECT STRING_AGG(Salary::TEXT, ',') FROM employees ORDER BY ID ) = ( SELECT STRING_AGG(Salary::TEXT, ',') FROM employees ORDER BY Salary DESC ) THEN 'true' ELSE 'false' END AS is_strictly_descending;
适配说明:
- MySQL替换为
GROUP_CONCAT,Oracle替换为LISTAGG。 - 若存在重复薪资,需补充ID排序逻辑(如
ORDER BY Salary DESC, ID),避免因薪资相同导致的误判。
方法3:自连接检查违规行
通过自连接直接查找“上方行薪资≤下方行薪资”的违规记录:
SELECT CASE WHEN EXISTS ( SELECT 1 FROM employees e1 JOIN employees e2 ON e1.ID < e2.ID AND e1.Salary <= e2.Salary ) THEN 'false' ELSE 'true' END AS is_strictly_descending;
逻辑说明:
- 自连接条件
e1.ID < e2.ID确保e1在e2的上方,e1.Salary <= e2.Salary匹配违规行。 - 只要存在违规行,就返回
false;否则返回true。
内容的提问来源于stack exchange,提问作者praveenraj4ever
相关产品推荐
相关产品推荐

