SQL JOIN 与窗口函数如何配合?

来源:中国站长站作者:小师妹头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL JOIN 与窗口函数如何配合?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL JOIN 与窗口函数如何配合?》有用,将其分享出去将是对创作者最好的鼓励。

SQL JOIN和窗口函数是SQL查询中两个非常核心的功能,前者用于实现多表数据的关联拼接,后者用于在不改变原有结果集行数的前提下完成分组内的计算、排序等操作。在实际的数据分析场景中,单独使用其中一个往往无法满足复杂需求,将两者合理配合可以高效解决很多跨表统计、组内排名类的问题。

SQL JOIN 与窗口函数如何配合?

JOIN与窗口函数的基础概念

JOIN的作用

JOIN用于根据两个或多个表之间的关联字段,将分散在不同表中的数据拼接成一张完整的结果集。常见的JOIN类型包括INNER JOIN、LEFT JOIN、RIGHT JOIN等,不同的JOIN类型决定了结果集中包含哪些匹配或不匹配的数据行。

窗口函数的作用

窗口函数可以对结果集的一个子集(称为窗口)进行计算,计算时不会将多行合并成一行,而是为每一行返回一个对应的计算结果。常见的窗口函数包括排序类的ROW_NUMBER()RANK(),聚合类的SUM() OVER()AVG() OVER()等。

JOIN与窗口函数的配合逻辑

两者的配合通常分为两个步骤,第一步先用JOIN将需要的数据从多个表中关联出来,得到一个基础的结果集;第二步在这个基础结果集上应用窗口函数,完成分组内的计算或排序。需要注意的是,窗口函数的执行顺序在JOIN之后,因此窗口函数处理的是JOIN完成后的最终结果集。

常见配合场景与代码示例

场景一:跨表关联后做组内排名

需求:查询每个部门下员工的薪资排名,员工信息存在employee表,部门信息存在department表,需要通过dept_id关联两个表。

首先创建两张测试表并插入测试数据:

-- 创建部门表
CREATE TABLE department (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(50)
);

-- 创建员工表
CREATE TABLE employee (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50),
    dept_id INT,
    salary DECIMAL(10,2)
);

-- 插入部门测试数据
INSERT INTO department VALUES (1, '技术部');
INSERT INTO department VALUES (2, '市场部');

-- 插入员工测试数据
INSERT INTO employee VALUES (1, '张三', 1, 12000);
INSERT INTO employee VALUES (2, '李四', 1, 15000);
INSERT INTO employee VALUES (3, '王五', 1, 12000);
INSERT INTO employee VALUES (4, '赵六', 2, 10000);
INSERT INTO employee VALUES (5, '钱七', 2, 13000);

使用JOIN关联两张表,再用窗口函数做部门内的薪资排名:

SELECT 
    d.dept_name AS 部门名称,
    e.emp_name AS 员工姓名,
    e.salary AS 薪资,
    -- 按部门分组,组内按薪资降序排名
    RANK() OVER (PARTITION BY d.dept_id ORDER BY e.salary DESC) AS 部门薪资排名
FROM employee e
INNER JOIN department d ON e.dept_id = d.dept_id;

执行上述查询后,会得到每个部门下员工的薪资排名,相同薪资的员工排名相同,下一个排名会跳过重复的位数。

场景二:关联后计算组内累计值

需求:查询每个员工的薪资,以及所在部门的薪资累计总和,同样需要关联员工表和部门表。

基于上面的测试表,使用以下查询实现:

SELECT 
    d.dept_name AS 部门名称,
    e.emp_name AS 员工姓名,
    e.salary AS 薪资,
    -- 按部门分组,组内按员工ID排序,计算薪资累计和
    SUM(e.salary) OVER (PARTITION BY d.dept_id ORDER BY e.emp_id) AS 部门累计薪资
FROM employee e
INNER JOIN department d ON e.dept_id = d.dept_id;

这个查询会先通过JOIN拿到每个员工对应的部门名称,然后窗口函数会按部门分组,组内按员工ID排序,逐步累加薪资得到累计值。

场景三:LEFT JOIN后处理缺失数据的窗口计算

需求:查询所有部门的信息,以及每个部门下的最高薪资,如果部门没有员工则最高薪资显示为NULL。

使用LEFT JOIN关联,再配合窗口函数的最大值计算:

SELECT 
    d.dept_name AS 部门名称,
    e.emp_name AS 员工姓名,
    e.salary AS 薪资,
    -- 按部门分组,计算组内最高薪资
    MAX(e.salary) OVER (PARTITION BY d.dept_id) AS 部门最高薪资
FROM department d
LEFT JOIN employee e ON d.dept_id = e.dept_id;

这里使用LEFT JOIN保证所有部门都会出现在结果集中,即使部门没有员工,窗口函数也会为该部门的所有行返回NULL作为最高薪资。

配合使用的注意事项

  • JOIN的执行顺序在窗口函数之前,因此窗口函数的PARTITION BY和ORDER BY只能使用JOIN之后结果集中存在的字段。
  • 如果JOIN之后结果集的行数较多,窗口函数的计算可能会消耗较多资源,需要合理设计索引提升查询效率。
  • 当使用LEFT JOIN等可能返回NULL值的关联方式时,窗口函数处理NULL值的逻辑需要和实际需求匹配,比如可以用COALESCE函数转换NULL值。

总结

SQL JOIN和窗口函数的配合是处理复杂查询的有效方式,JOIN负责整合多表数据,窗口函数负责在整合后的数据上做精细化计算。只要掌握先关联再计算的逻辑,就能应对大部分跨表分组统计、排名类的需求,减少复杂子查询的使用,让SQL代码更简洁易读。

SQL_JOIN窗口函数SQL查询数据分析修改时间:2026-07-02 09:27:30

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