导读:本期聚焦于小伙伴创作的《如何在SQL中查询各部门薪资前三名_利用ROW_NUMBER窗口函数实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在SQL中查询各部门薪资前三名_利用ROW_NUMBER窗口函数实现》有用,将其分享出去将是对创作者最好的鼓励。

在SQL数据处理的实际业务场景里,查询各部门薪资前三名是人力资源、财务部门常提出的需求,传统的子查询或者自连接方式不仅代码逻辑复杂,执行效率也不够理想,使用ROW_NUMBER窗口函数可以简洁高效地完成这个需求。

如何在SQL中查询各部门薪资前三名_利用ROW_NUMBER窗口函数实现

一、准备工作:创建测试数据表

首先我们需要创建一个员工薪资表,用于存储员工所属部门、员工姓名和薪资信息,方便后续演示查询逻辑,建表语句如下:

-- 创建员工薪资表
CREATE TABLE employee_salary (
    id INT PRIMARY KEY AUTO_INCREMENT,
    dept_name VARCHAR(50) NOT NULL COMMENT '部门名称',
    emp_name VARCHAR(50) NOT NULL COMMENT '员工姓名',
    salary DECIMAL(10,2) NOT NULL COMMENT '员工薪资'
);

-- 插入测试数据
INSERT INTO employee_salary (dept_name, emp_name, salary) VALUES
('技术部', '张三', 15000.00),
('技术部', '李四', 18000.00),
('技术部', '王五', 18000.00),
('技术部', '赵六', 12000.00),
('技术部', '孙七', 20000.00),
('产品部', '周八', 16000.00),
('产品部', '吴九', 14000.00),
('产品部', '郑十', 17000.00),
('产品部', '冯十一', 15000.00),
('运营部', '陈十二', 13000.00),
('运营部', '褚十三', 11000.00),
('运营部', '卫十四', 14000.00);

二、ROW_NUMBER窗口函数基础用法

ROW_NUMBER是SQL中常用的窗口函数,作用是对查询结果集的每一行分配一个唯一的连续整数,整数的值取决于ORDER BY子句指定的排序规则,基本语法如下:

ROW_NUMBER() OVER (
    PARTITION BY 分组字段 
    ORDER BY 排序字段 [ASC|DESC]
)

其中PARTITION BY用于指定分组的字段,这里我们需要按部门分组,所以填写dept_nameORDER BY用于指定每个分组内的排序规则,查询薪资前三名需要按薪资降序排列,所以填写salary DESC

三、完整实现各部门薪资前三名查询

结合ROW_NUMBER函数和子查询,我们可以快速得到各部门薪资前三名的完整结果,具体SQL如下:

-- 查询各部门薪资前三名
SELECT 
    dept_name,
    emp_name,
    salary
FROM (
    -- 子查询:给每个部门的员工按薪资降序编号
    SELECT 
        dept_name,
        emp_name,
        salary,
        ROW_NUMBER() OVER (
            PARTITION BY dept_name 
            ORDER BY salary DESC
        ) AS salary_rank
    FROM employee_salary
) tmp
-- 筛选排名前三的记录
WHERE salary_rank <= 3;

上述SQL的执行逻辑是先通过子查询为每个部门的员工按薪资从高到低生成序号,序号为1的是该部门薪资最高的员工,序号为2的是第二高,以此类推,最后外层查询筛选出序号小于等于3的记录,就得到了各部门薪资前三名。

四、不同窗口函数的区别说明

如果是薪资有并列的情况,ROW_NUMBER会给并列的薪资分配不同的序号,比如两个员工薪资都是18000,一个排第2,一个排第3,如果你需要并列薪资占同一个名次,可以换成DENSE_RANK函数,语法和ROW_NUMBER类似:

-- 使用DENSE_RANK实现并列薪资同排名的前三名查询
SELECT 
    dept_name,
    emp_name,
    salary
FROM (
    SELECT 
        dept_name,
        emp_name,
        salary,
        DENSE_RANK() OVER (
            PARTITION BY dept_name 
            ORDER BY salary DESC
        ) AS salary_rank
    FROM employee_salary
) tmp
WHERE salary_rank <= 3;

两者的核心区别如下:

  • ROW_NUMBER:不管薪资是否相同,都会生成连续不重复的唯一序号,适合需要明确排名顺序、不允许多个记录占同一个名次的场景
  • DENSE_RANK:相同薪资会分配相同的序号,下一个不同薪资的序号不会跳过,比如两个第2名之后,下一个是3名,适合允许并列排名的场景
  • RANK:相同薪资分配相同序号,但是下一个不同薪资的序号会跳过占用的名次,比如两个第2名之后,下一个是4名

五、实际业务注意事项

在实际使用这个查询逻辑时,需要注意以下几点:

  • 如果薪资字段存在NULL值,ORDER BY DESC时NULL值会排在最前面,需要根据业务需求处理NULL值,比如用COALESCE(salary, 0)将NULL转为0再排序
  • 如果部门名称存在重复或者大小写不一致的情况,需要先做数据清洗,保证PARTITION BY分组的准确性
  • 如果数据量较大,建议在dept_name和salary字段上建立联合索引,提升窗口函数的执行效率

SQLROW_NUMBER窗口函数薪资查询修改时间:2026-07-15 20:24:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。