MySQL分组排序与排名实战:从窗口函数到性能优化
1. 从“分组排序”到“排名”一个被低估的SQL核心技能在数据库日常开发中我们经常遇到这样的需求先按某个维度分组然后在每个组内进行排序最后甚至要给出一个明确的排名。比如计算每个部门内员工的绩效排名找出每个班级里成绩前三的学生或者统计每个商品类别下销量最高的产品。这些需求听起来很基础但很多开发者甚至是有几年经验的在面对复杂的排名规则如并列排名、连续排名时依然会感到棘手要么写出性能低下的嵌套查询要么干脆在应用层用代码暴力解决。这背后反映出的是对MySQL窗口函数Window Functions这一强大特性的不熟悉。自从MySQL 8.0引入窗口函数后分组排序和排名问题有了优雅且高效的解决方案。今天我们就抛开那些零散的教程系统地、完整地梳理一遍在MySQL中实现分组查询排序和排名的所有核心方法从基础的GROUP BYORDER BY到进阶的窗口函数ROW_NUMBER()、RANK()、DENSE_RANK()再到如何在低版本MySQL中模拟这些功能。我会结合真实的业务场景拆解每一步的原理和选择背后的逻辑并分享那些官方文档里不会写的性能陷阱和调试技巧。2. 基础构建理解分组与排序的底层逻辑在深入排名之前我们必须夯实基础分组和排序。很多人会把GROUP BY和ORDER BY的顺序搞混或者不理解它们执行阶段的差异这直接导致了错误的查询结果。2.1GROUP BY与ORDER BY的执行顺序与本质区别这是一个最常见的误区认为SELECT ... FROM ... WHERE ... GROUP BY ... ORDER BY ...这个书写顺序就是执行顺序。实际上在逻辑处理阶段它们的顺序是FROM / JOIN: 确定数据来源。WHERE: 对行进行过滤。GROUP BY: 将过滤后的行进行分组聚合。一旦执行了GROUP BY后续操作SELECT列表、HAVING、ORDER BY处理的对象就从“原始行”变成了“分组”。HAVING: 对分组后的结果进行过滤。SELECT: 计算选择列表中的表达式包括聚合函数如SUM,COUNT。ORDER BY: 对最终的结果集进行排序。LIMIT: 限制返回的行数。关键点在于ORDER BY是对GROUP BY聚合后的结果进行排序而不是在组内排序。例如你想看每个部门的平均工资并从高到低排序这用GROUP BY department ORDER BY AVG(salary) DESC是没问题的。但如果你想看每个部门内部员工按工资从高到低排序ORDER BY放在GROUP BY后面是无效的因为此时数据已经按部门聚合成一行了。一个经典的错误示例-- 错误试图在分组后对组内成员排序 SELECT department, name, salary FROM employees GROUP BY department ORDER BY salary DESC;这个查询在语义上就是错误的name和salary在非聚合且不在GROUP BY中在严格模式下会报错即使某些宽松模式下能执行结果也绝非你想要的“组内排序”。2.2 实现“组内排序”的朴素方法子查询在窗口函数普及之前实现组内排序的标准做法是使用关联子查询。其核心思想是对于主查询的每一行在子查询中计算一个值这个值能反映该行在其所属分组中的排序位置。假设我们有表scores(id, student_id, course, score)想找出每个课程course分数最高的学生。方法使用标量子查询计算排名SELECT s1.*, (SELECT COUNT(DISTINCT s2.score) FROM scores s2 WHERE s2.course s1.course AND s2.score s1.score) AS rank_in_course FROM scores s1 ORDER BY s1.course, rank_in_course;原理解析对于s1表中的每一行子查询都会执行一次。子查询的作用是在同一个课程s2.course s1.course中找出所有分数不低于当前行分数s2.score s1.score的不重复分数的个数。这个个数就是当前行分数在组内的“排名”。分数最高的人大于等于他的分数只有他这一个分数所以排名是1。这种方法的优缺点非常明显优点兼容所有MySQL版本逻辑清晰是理解排名本质的好例子。缺点性能极差。如果主表有N行这个查询的复杂度接近O(N²)因为每一行都要触发一次子查询的全表或索引扫描。在大数据量下完全不可用。实操心得在维护老系统MySQL 5.7或更早时如果遇到这类需求且数据量不大这可能是一种临时解决方案。但一定要评估性能并考虑在(course, score)上建立复合索引来稍微优化子查询。更好的建议是推动升级到MySQL 8.0。3. 窗口函数分组排序与排名的“终极武器”MySQL 8.0引入的窗口函数彻底改变了游戏规则。它允许你在不减少行数即不进行GROUP BY聚合的情况下对数据的“窗口”进行计算。这个“窗口”可以由PARTITION BY分组和ORDER BY排序来定义。3.1ROW_NUMBER()连续的、唯一的排名ROW_NUMBER()为结果集中的每一行分配一个唯一的、连续的整数序号从1开始。即使两行的排序值完全相同它们的行号也不同顺序不确定但必然不同。基本语法ROW_NUMBER() OVER ( [PARTITION BY partition_expression, ... ] ORDER BY sort_expression [ASC|DESC], ... ) AS row_num场景示例给每个部门的员工按工资从高到低编号工资相同的任意排序但编号不同。SELECT department, name, salary, ROW_NUMBER() OVER ( PARTITION BY department ORDER BY salary DESC ) AS dept_salary_rank FROM employees ORDER BY department, dept_salary_rank;结果可能如下departmentnamesalarydept_salary_rankTechAlice95001TechBob90002TechCharlie90003SalesDavid88001SalesEve85002为什么选择ROW_NUMBER()当你需要绝对唯一的标识时使用它例如分页查询中获取每个组的第N条记录如“每个类别最新的一条新闻”。它不处理并列情况这既是特点也是限制。3.2RANK()与DENSE_RANK()处理并列排名这是排名问题中的核心难点也是面试常考点。两者都处理并列但“留空”策略不同。RANK()并列的排名相同但会留下空位。例如两个并列第一下一个排名是3。DENSE_RANK()并列的排名相同且不留空位排名连续。例如两个并列第一下一个排名是2。语法与ROW_NUMBER()完全相同只是函数名不同。对比示例按分数排名。SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) as row_num, RANK() OVER (ORDER BY score DESC) as rank, DENSE_RANK() OVER (ORDER BY score DESC) as dense_rank FROM exam_results;结果namescorerow_numrankdense_rank张三100111李四100211王五95332赵六90443如何选择选择RANK()当并列排名后后续名次需要反映“你前面有多少人”时。例如奥运会奖牌榜两个金牌并列第一银牌得主就是第三名。这是最常见的体育排名规则。选择DENSE_RANK()当排名需要连续数字且并列不影响后续编号时。例如划分等级A级、B级100分和99分都是A级排名195分是B级排名2。踩坑实录在一次业绩报表开发中产品经理要求“销售排名业绩相同的并列但下一个名次要顺延”。我下意识用了DENSE_RANK()结果排名是连续的但销售团队认为这没有体现竞争人数产生了歧义。最终改为RANK()才符合业务预期。关键点一定要和业务方确认并列时的排名规则。3.3 窗口函数的进阶用法与性能优化窗口函数强大之处不止于此结合其他子句和函数能解决更复杂的问题。1. 获取每组前N名经典Top N问题以前需要用复杂的自连接或子查询现在用ROW_NUMBER()加一层包装即可。-- 获取每个部门工资前三的员工 WITH ranked_employees AS ( SELECT department, name, salary, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn FROM employees ) SELECT * FROM ranked_employees WHERE rn 3;这里使用了公共表表达式CTE也是MySQL 8.0引入让查询更清晰。你也可以用派生表。2. 计算累计、移动平均等窗口框架Window frame是另一个核心概念用ROWS BETWEEN ... AND ...或RANGE BETWEEN ... AND ...定义。-- 计算每个员工按入职日期排序的累计工资部门内 SELECT department, name, hire_date, salary, SUM(salary) OVER ( PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_salary_dept FROM employees;3. 性能优化要点窗口函数通常比等效的子查询性能好得多但使用不当也会成为瓶颈。索引是关键确保OVER()子句中的PARTITION BY和ORDER BY字段上有合适的索引。例如对于PARTITION BY department ORDER BY salary DESC建立索引(department, salary DESC)会极大提升性能。DESC在MySQL 8.0中可以被降序索引支持。避免全表扫描窗口函数的计算是在WHERE过滤和JOIN之后进行的。如果能在之前用WHERE条件大幅减少数据量会显著提升速度。警惕RANGE框架默认的RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW在遇到排序值相同的大量行时可能会进行大量计算。如果业务允许明确使用ROWS框架通常性能更可预测。4. 在MySQL 8.0之前模拟窗口函数的“黑魔法”如果你不幸需要维护MySQL 5.7或更早的版本又需要实现排名功能就需要一些“黑魔法”。最常用的方法是使用会话变量。4.1 使用变量模拟ROW_NUMBER()思路是手动维护一个计数器当分组字段变化时重置。SET row_number 0; SET current_dept ; SELECT department, name, salary, row_number : CASE WHEN current_dept department THEN row_number 1 ELSE 1 END AS dept_salary_rank, current_dept : department AS dummy -- 更新当前部门变量 FROM employees ORDER BY department, salary DESC;原理解析ORDER BY department, salary DESC确保数据先按部门、再按工资排好序。对于每一行CASE语句判断如果当前行的department等于变量current_dept即还在同一个部门内则行号row_number加1否则到了新部门行号重置为1。最后将当前行的department赋值给current_dept供下一行判断使用。重要警告这种方法的正确性严重依赖于ORDER BY的执行顺序和变量赋值的顺序。在MySQL的某些版本或复杂查询中执行计划可能导致变量计算顺序与预期不符从而得到错误结果。它不稳定不推荐在生产环境使用仅作理解原理之用。4.2 使用变量模拟RANK()和DENSE_RANK()模拟RANK()需要额外变量记录上一行的排序值以判断是否并列。-- 模拟RANK() SET rank 0; SET prev_score NULL; SET prev_rank 0; SELECT name, score, rank : IF(prev_score score, prev_rank, rank 1) AS rank, prev_rank : rank AS dummy_rank, prev_score : score AS dummy_score FROM exam_results ORDER BY score DESC;模拟DENSE_RANK()则更简单一些只在排序值变化时增加排名。-- 模拟DENSE_RANK() SET dense_rank 0; SET prev_score NULL; SELECT name, score, dense_rank : IF(prev_score score, dense_rank, dense_rank 1) AS dense_rank, prev_score : score AS dummy_score FROM exam_results ORDER BY score DESC;这些方法的通病可读性差逻辑隐藏在变量赋值中难以理解和维护。稳定性风险如前述依赖执行计划。无法并行变量是会话级的难以在分布式或复杂查询中正确使用。调试困难一旦出错排查成本极高。我的强烈建议如果业务强依赖排名功能且数据库版本老旧最务实的方案不是死磕SQL模拟而是要么申请升级到MySQL 8.0要么将排名计算逻辑转移到应用层例如用Java/Python读取分组数据后在内存中计算排名。后者的可控性和可维护性远高于不稳定的SQL变量技巧。5. 实战一个完整的分组排名报表查询剖析让我们通过一个综合案例把前面的知识串联起来。假设我们有一个电商订单详情表order_items结构如下CREATE TABLE order_items ( order_id INT, product_category VARCHAR(50), product_id INT, quantity INT, price DECIMAL(10,2), sale_date DATE );需求生成一份月度报表展示每个月、每个产品类别下销量quantity排名前3的产品并显示该产品在本类别内的排名以及相比上个月的销量排名变化情况。这个需求融合了分组、排名、多期数据对比。步骤拆解与实现步骤1计算基础数据与月度排名首先我们需要聚合出每个产品在每个月的总销量并计算其在各自类别内的月度排名。WITH monthly_sales AS ( SELECT DATE_FORMAT(sale_date, %Y-%m) AS sale_month, product_category, product_id, SUM(quantity) AS total_quantity, -- 使用RANK()因为业务可能关心并列情况下的后续名次 RANK() OVER ( PARTITION BY sale_month, product_category ORDER BY SUM(quantity) DESC ) AS category_rank_monthly FROM order_items GROUP BY sale_month, product_category, product_id ) SELECT * FROM monthly_sales;这里使用了RANK()并按照sale_month和product_category进行分区按销量降序排列。步骤2获取上月排名数据我们需要关联出每个产品在上个月的排名用于计算变化。使用LAG()窗口函数可以优雅地访问前一行的数据。WITH monthly_sales AS (...), -- 同上 sales_with_lag AS ( SELECT sale_month, product_category, product_id, total_quantity, category_rank_monthly, -- 获取上个月在同类别内的排名 LAG(category_rank_monthly) OVER ( PARTITION BY product_category, product_id ORDER BY sale_month ) AS last_month_rank FROM monthly_sales ) SELECT * FROM sales_with_lag;LAG(category_rank_monthly, 1)表示取当前行之前1行的category_rank_monthly值。PARTITION BY product_category, product_id确保了我们在同一个产品的同一个类别内跨月份比较。ORDER BY sale_month则定义了时间顺序。步骤3筛选Top 3并计算排名变化最后从上述结果中筛选出每月每类排名前3的产品并计算排名变化。WITH monthly_sales AS (...), sales_with_lag AS (...) SELECT sale_month, product_category, product_id, total_quantity, category_rank_monthly AS current_rank, last_month_rank, -- 计算排名变化正数表示进步负数表示退步NULL表示新上榜或上月无数据 CASE WHEN last_month_rank IS NULL THEN New / NA ELSE CAST((last_month_rank - category_rank_monthly) AS CHAR) END AS rank_change FROM sales_with_lag WHERE category_rank_monthly 3 -- 筛选每月每类Top 3 ORDER BY sale_month DESC, product_category, category_rank_monthly;性能考量 这个查询涉及多层CTE和窗口函数在数据量大时可能会慢。优化点包括在order_items表上建立索引(sale_date, product_category, product_id, quantity)。这个索引可以高效地支持第一步的聚合和排序。考虑物化monthly_sales这个中间结果特别是如果报表是定期如每天生成一次。可以将其写入一张临时表或汇总表后续的排名变化分析基于此表进行避免每次都从海量明细数据开始计算。这个案例展示了如何将RANK()、LAG()、CTE和CASE表达式组合使用解决一个相对复杂的业务分析需求。思路是先通过CTE将复杂查询分解为逻辑清晰的步骤每一步都专注于一个明确的目标最后再组合起来。这种“分而治之”的思维在编写复杂SQL时至关重要。6. 常见陷阱、调试技巧与选型指南即使掌握了语法在实际使用中依然会踩坑。这里分享几个我亲身经历或高频看到的问题。陷阱1在WHERE或HAVING中引用窗口函数列这是语法错误。窗口函数是在SELECT阶段计算的而WHERE和HAVING在它之前执行。-- 错误 SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) as rn FROM employees WHERE rn 5; -- 这里不能使用rn -- 正确做法使用子查询或CTE包装 WITH ranked AS ( SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) as rn FROM employees ) SELECT * FROM ranked WHERE rn 5;陷阱2忽略NULL值对排序的影响在ORDER BY中NULL值默认被视为最小值ASC排序时排在最前DESC时排在最后。这可能会影响排名结果。如果你希望NULL值排在最后无论升序降序可以使用ORDER BY column_name IS NULL, column_name (ASC/DESC)。陷阱3PARTITION BY和GROUP BY的混淆记住PARTITION BY是窗口函数的一部分它定义“窗口”但不聚合数据结果行数不变。GROUP BY是聚合会减少行数。两者可以同时出现在一个查询中但作用不同。-- 计算每个部门的平均工资同时显示每个员工工资与部门平均工资的差值 SELECT department, name, salary, AVG(salary) OVER (PARTITION BY department) as dept_avg_salary, salary - AVG(salary) OVER (PARTITION BY department) as diff_from_avg FROM employees; -- 这里没有GROUP BY返回的是每个员工的记录。调试技巧逐步验证对于复杂的多层窗口函数查询像我们之前的实战案例一样使用CTE并逐步SELECT * FROM cte_name查看中间结果确保每一步都符合预期。简化问题如果排名结果不对先去掉PARTITION BY看全局排名是否正确。再逐步加上PARTITION BY和复杂的ORDER BY表达式。利用EXPLAIN使用EXPLAIN或EXPLAIN ANALYZEMySQL 8.0.18查看执行计划确认是否用到了你为PARTITION BY和ORDER BY字段建立的索引。关注“Using filesort”字样如果出现且数据量大说明需要优化索引。技术选型指南MySQL 8.0无脑选择窗口函数。ROW_NUMBER()用于取唯一Top NRANK()和DENSE_RANK()根据业务规则选择。这是性能、可读性和功能性的最佳组合。MySQL 5.7及以下且数据量小、需求简单可以考虑使用关联子查询但务必做好性能测试和索引优化。MySQL 5.7及以下且需求复杂或数据量大强烈建议将排名逻辑移至应用层。在内存中对分组后的数据集进行排序和排名计算可控性更强。或者这是推动数据库升级的一个强有力的理由。任何版本对于超大数据集即使使用窗口函数也可能面临性能压力。需要考虑分层汇总、物化视图、或使用专门的分析型数据库来处理。窗口函数和分组排名是SQL从“能查询”到“善分析”的关键跨越。它让很多原本需要多次查询或应用层复杂处理的任务在数据库层面一站式高效完成。理解并熟练运用ROW_NUMBER()、RANK()、DENSE_RANK()这三个核心函数以及PARTITION BY、ORDER BY和窗口框架的概念能极大提升你解决数据排序和排名问题的能力。

相关新闻

零阶矩、一阶矩、二阶矩详解:从物理意义到图像识别与数据分析实战

零阶矩、一阶矩、二阶矩详解:从物理意义到图像识别与数据分析实战

1. 从“矩”说起:一个被低估的数学工具“矩”这个概念,听起来有点抽象,像是高等数学课本里才会出现的名词。但你可能不知道,从你手机里的人脸识别解锁,到医生看CT片判断病灶,再到金融分析师评估投资风险&am…

2026/8/6 4:32:47 阅读更多 →
DeepSeek AI编程助手实战指南:从提示工程到开发全流程应用

DeepSeek AI编程助手实战指南:从提示工程到开发全流程应用

最近在 AI 助手圈子里,一个有趣的“梗”正在流传: “我是皇帝,DeepSeek 乃朕之丞相,望周知” 。这当然不是真的在讨论历史或权力,而是开发者们用这种诙谐的方式,表达对 DeepSeek 模型在编程和问题解决中强…

2026/8/5 2:21:04 阅读更多 →
揭秘百家号算法最新变动:AI写稿如何绕过限流雷区,3步通过原创审核

揭秘百家号算法最新变动:AI写稿如何绕过限流雷区,3步通过原创审核

更多请点击: https://kaifayun.com 第一章:揭秘百家号算法最新变动:AI写稿如何绕过限流雷区,3步通过原创审核 近期百家号升级内容质量识别模型,引入多模态语义指纹比对与行为时序建模机制,对AI生成内容的识…

2026/8/5 2:21:04 阅读更多 →

最新新闻

Unity混合树深度解析:从原理到实战,打造流畅角色动画

Unity混合树深度解析:从原理到实战,打造流畅角色动画

1. 项目概述:为什么混合动画是游戏角色流畅度的灵魂如果你在Unity里做过角色动画,肯定遇到过这种尴尬:角色从静止到奔跑,动作切换得像机器人一样僵硬;或者角色在转向时,上半身和下半身像脱节了一样不协调。…

2026/8/6 5:09:05 阅读更多 →
MySQL权限管理:从基础到实战的安全配置指南

MySQL权限管理:从基础到实战的安全配置指南

1. MySQL权限管理核心概念解析权限管理是MySQL数据库安全体系中最关键的组成部分之一。作为DBA,我经常遇到因为权限配置不当导致的安全事故。MySQL的权限系统采用"基于角色"的设计理念,通过用户账号与权限对象的组合实现精细控制。每个MySQL用…

2026/8/6 5:09:05 阅读更多 →
如何5分钟打造你的专属桌面虚拟伙伴:基于PySide6的完整桌宠系统指南

如何5分钟打造你的专属桌面虚拟伙伴:基于PySide6的完整桌宠系统指南

如何5分钟打造你的专属桌面虚拟伙伴:基于PySide6的完整桌宠系统指南 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 你是否厌倦了单调的电脑桌面?是否曾幻…

2026/8/6 5:09:05 阅读更多 →
3分钟极速上手:chinese-address-generator 让中国地址数据生成变得如此简单

3分钟极速上手:chinese-address-generator 让中国地址数据生成变得如此简单

3分钟极速上手:chinese-address-generator 让中国地址数据生成变得如此简单 【免费下载链接】chinese-address-generator 中国地址生成器 - 三级地址 四级地址 随机生成完整地址 项目地址: https://gitcode.com/gh_mirrors/ch/chinese-address-generator 在软…

2026/8/6 5:09:04 阅读更多 →
3步完成Android Studio中文界面切换:终极完整指南

3步完成Android Studio中文界面切换:终极完整指南

3步完成Android Studio中文界面切换:终极完整指南 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 你是否曾经因为Andr…

2026/8/6 5:09:04 阅读更多 →
003010002_Border控件(边框布局)的案例代码解析

003010002_Border控件(边框布局)的案例代码解析

003010002_Border 控件(边框布局)的案例代码解析**摘要:**本文深入解析 WPF 中 UpdateDeviceStatus 方法的完整实现,通过传入背景色、边框色、指示灯颜色和状态文本四个参数,统一更新 Border、Ellipse、TextBlock 控件…

2026/8/6 5:08:04 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →