news 2026/10/22 6:38:59

SQL窗口函数速查:从OVER语法到五大高频坑与实战模板

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL窗口函数速查:从OVER语法到五大高频坑与实战模板

简介:《SQL窗口函数速查表》是一份面向数据分析师、数据库管理员及开发人员的实用参考手册,系统梳理了窗口函数的基本概念、三大类型(排名、行序号、聚合函数)及完整语法结构,帮助读者在处理复杂SQL查询时快速上手。资源包内含1个PDF文件,压缩包大小841KB,体量轻巧,便于离线查阅和打印。速查表采用分类表格与示例相结合的方式,文档按排名、行序号、聚合等类别清晰分类,并配有ROW_NUMBER()、RANK()、DENSE_RANK()、LEAD()、LAG()及SUM、AVG等常用函数的示例代码和结果说明,可直观理解每个函数的分组、排序与窗口范围定义方式。无论用于数据库运维、数据探索,还是开发报表功能和学术教学,这份速查表都能显著提升窗口函数的应用效率,是系统学习与日常速查两相宜的实用工具。目前已有255人学习使用。

1. 最被低估的SQL能力:窗口函数不是聚合,是“不折叠明细的聚合”

刚接触窗口函数时,我最大的误区是把它当成聚合函数的语法糖。直到在某个电商订单库里写分组TopN,用子查询加自连接折腾了大半天,最后被一条ROW_NUMBER() OVER (PARTITION BY ...)当场解决,我才意识到窗口函数的真正价值:它在计算完聚合值之后,并不会把多行压成一行,而是把计算结果原样贴回每一行。这意味着原始数据一条不丢,分析逻辑却往前跨了一大步。这份《SQL窗口函数速查表.pdf》就是围绕这个核心差异展开的,把排名、偏移、聚合三类窗口函数和OVER语法收进同一份速查里。数据分析师、数仓开发、后端写SQL的人都能用,新手对照示例做一遍,熟手用来确认默认值和边界行为也省事。

2. 先看懂OVER子句:窗口函数的底层逻辑与语法结构

窗口函数的名字五花八门,ROW_NUMBER、RANK、SUM、LEAD各管一摊,但它们的共同骨架只有一个:函数名后面那个OVER()。速查表的第一部分就把这个核心语法单拎出来讲,这也是我觉得整份PDF最值钱的部分——函数名记不住可以现查,OVER的语义看不懂,写出来的SQL基本靠猜。

2.1 窗口函数与传统聚合的本质差异:为什么GROUP BY做不到这件事

普通聚合函数的行为是“多行进,一行出”。比如按部门统计工资总额,GROUP BY dept_id会把每个部门折叠成一条记录,部门里的员工明细全部消失。窗口函数同样是算总数,但写法变成SUM(salary) OVER (PARTITION BY dept_id),结果是每一行员工数据都还在,旁边多出一列部门总额。

SELECT emp_id, emp_name, dept_id, salary, SUM(salary) OVER (PARTITION BY dept_id) AS dept_total FROM employee ORDER BY dept_id, emp_id;

这段SQL我经常拿来给刚入门的同事讲窗口函数。SUM(salary) OVER (PARTITION BY dept_id)先按部门分组,再在每组内做求和,最后把求和结果附加到组内每一行。注意观察执行结果:dept_total在同一个部门的所有员工行上是重复出现的值,这正是窗口函数的标志性特征。如果你把PARTITION BY dept_id去掉,写成SUM(salary) OVER (),那整个结果集会被当成一个大窗口,所有员工行上都会显示全公司的工资总额。

这个差异在实际报表里非常有用。比如要同时展示员工个人工资和他所属部门的平均工资,传统做法是两条SQL查完再关联,窗口函数一条SQL就带出来了。速查表里把这类聚合函数单独归成一类,其底层逻辑就是“在窗口内做聚合,但保留原始行粒度”。

2.2 OVER三件套:PARTITION BY、ORDER BY和frame的职责分工

所有窗口函数的窗口定义都由三部分组成:分区、排序、窗口范围(frame)。速查表给出的语法结构可以浓缩成下面这个模板:

function_name(expression) OVER ( [PARTITION BY col1, col2] [ORDER BY col3 [ASC | DESC]] [ROWS | RANGE BETWEEN frame_start AND frame_end] )

三个可选部分的作用差异很大,我按理解顺序拆开说。

PARTITION BY负责横向切分,把整个结果集按指定列的值分成若干独立小组,各组之间互不干扰。它和GROUP BY的分组概念很像,但不做折叠。

ORDER BY负责组内排序。注意它只决定窗口内行的先后顺序,不会改变查询结果的最终输出顺序,除非你在外层再加一个ORDER BY。这是很多新手第一个翻车点:以为写了ORDER BY结果集就该排好序,实际上结果集的排序由最外层的ORDER BY决定。

frame是整个OVER子句里最容易被忽略的部分。它的作用是在已经排好序的组内,再划一条“计算边界”,决定参与计算的行到底是哪些。下面这张表是速查表里frame部分的常见边界写法:

边界写法含义
UNBOUNDED PRECEDING从分区第一行开始
n PRECEDING从当前行往前数n行开始
CURRENT ROW从当前行开始
n FOLLOWING到当前行往后数n行结束
UNBOUNDED FOLLOWING到分区最后一行结束

这里有个必须背下来的默认行为:写了ORDER BY没写frame时,默认是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,即从分区起点到当前行的所有行;没写ORDER BY时,frame默认是整个分区。这两种默认值分别对应“累计值”和“组内总值”两种结果,很多线上SQL算出来的数不对,根源就在这里。

2.3 一个能直接抄的完整示例:四个窗口函数同屏对比

把以上概念放进同一个查询里,效果比分开讲直观得多。下面这个订单分析场景,我在好几个项目里都用过类似写法:

SELECT order_id, customer_id, order_date, order_amount, -- 每个客户的所有订单金额合计 SUM(order_amount) OVER (PARTITION BY customer_id) AS customer_total, -- 单笔订单金额占该客户总金额的比例 ROUND(order_amount * 1.0 / SUM(order_amount) OVER (PARTITION BY customer_id), 4) AS pct_of_customer, -- 按订单日期累加的客户累计金额 SUM(order_amount) OVER ( PARTITION BY customer_id ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_amount FROM orders ORDER BY customer_id, order_date;

逐列看这个查询:customer_total用的就是2.1节里的分组窗口,每个客户的订单行都带着自己的总额;pct_of_customer是单笔金额除以客户总金额,算比例时我把order_amount乘以1.0,这是为了避免整数除法直接截断成0;cumulative_amount才是体现frame威力的地方——ORDER BY order_date之后,frame从分区起点到当前行,每一行算的都是“截至目前”的累计值。

如果你从速查表翻到这一页,会发现PDF里的示例和我这个基本同一套路,但顺序更细致:先演示无排序的组内聚合,再演示带排序的累计聚合。建议你拿到手后不要跳着读,按它的分类顺序跑一遍,大于等于5个函数跑完,OVER子句的直觉就建立起来了。

3. 排名与偏移函数实战:ROW_NUMBER、RANK、DENSE_RANK、LEAD、LAG

速查表把排名函数和行序号函数分成两类,但实际业务里它们经常出现在同一个查询里。区别在于:排名函数解决“这行排第几”,偏移函数解决“旁边那行是什么”。两套函数单独看不难,放一起用才是报表里的常态。

3.1 三个排名函数:并列、跳号与连续,业务含义完全不同

很多人以为RANK和DENSE_RANK只是同一个功能的两种写法,这是大错特错。用一个成绩表就能说清楚三者的差异:

SELECT student_name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num, RANK() OVER (ORDER BY score DESC) AS rank_no, DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank_no FROM exam_score;

假设有三名同学同分,成绩按降序排列后,ROW_NUMBER()会给它们强行分配1、2、3,互不重复;RANK()会让它们并列第1,下一个不同分数的同学直接排到第4名,数字上跳号;DENSE_RANK()同样让同分并列第1,但下一个不同分数的同学排第2名,不跳号。三种逻辑对应三种业务口径:

函数并列时排名是否跳号典型业务场景
ROW_NUMBER不允许并列不适用取前N条、分页去重
RANK允许并列跳号竞赛排名,强调“后面还有多少人”
DENSE_RANK允许并列不跳号等级划分,如按分数段定级

速查表里每条函数下面都标注了返回规则,我建议你精读这一块。它还把容易混淆的ROW_NUMBER()和RANK()放在相邻位置,就是为了让你一眼看出差异:前者每行唯一,后者允许并列并跳过后续排名。

这里补一个边界行为:排序键为NULL时,三个函数的处理方式在各个数据库里并不一致。有的数据库把NULL当最大值排在最前,有的排到最后,还有的允许你通过NULLS LAST等子句手动指定。速查表引用了一些跨数据库兼容性说明,我在生产环境里都会显式声明NULL的排序方向,否则同一个SQL在两个引擎上跑出完全不同的排名,排查起来非常头疼。

3.2 LEAD与LAG:取前后行数据,计算同比环比的核心工具

LEAD和LAG是一对相反方向的偏移函数。LAG取当前行之前的第n行,LEAD取当前行之后的第n行,它们最常见的用途是算环比、同比、时间间隔这类“跟相邻记录比大小”的场景。

下面是用员工调薪记录计算每次调薪幅度的标准写法:

SELECT emp_id, salary_date, salary, LAG(salary) OVER (PARTITION BY emp_id ORDER BY salary_date) AS prev_salary, ROUND( (salary - LAG(salary) OVER (PARTITION BY emp_id ORDER BY salary_date)) * 100.0 / LAG(salary) OVER (PARTITION BY emp_id ORDER BY salary_date), 2 ) AS pct_change FROM salary_history ORDER BY emp_id, salary_date;

LAG(salary)只写了一个参数,默认取上一行;PARTITION BY emp_id保证每个员工单独计算,不然不同员工的调薪记录会串行;ORDER BY salary_date决定“上一行”的方向是时间上的前一条记录。pct_change就是本条薪资相对上一条的变化率。

这两个函数的完整参数形态是LAG(expr, offset, default)和LEAD(expr, offset, default)。第二个参数offset控制偏移行数,不写默认1;第三个参数default表示越界时返回的值,比如第一行没有“上一行”,默认返回NULL。速查表把这几个参数列得特别清楚,我一开始记不住default参数的位置,全靠这张表翻。还有个冷门技巧:offset参数可以写负数,LAG(x, -1)等价于LEAD(x, 1),但可读性差很多,一般不建议这么写。

如果想算同比,比如电商订单里这个月和上个月同一天的销售额,就把它和前12个月的记录比:LAG(amount, 12) OVER (PARTITION BY product_id ORDER BY month)。这种情况下offset不再是一行一行数,而是按排序键的偏移量,前提是你的数据里每个月都有一条记录,否则要结合数据补全一起做。

3.3 拿到速查表后,怎样快速定位一个函数

速查表的结构我是这么用的:先明确业务要干什么,再去对应分类里找函数名,最后抄一个示例代码验证。完整的查找路径可以拆成三步。

第一步,看函数分类。要判断某行在整个结果集里的位次,去“排名函数”找;要看前后行的值,去“行序号函数”找;要做累计求和、移动平均,去“聚合函数”找。第二步,核对函数签名。速查表里每个函数都给了参数列表和返回规则,重点看有没有default参数、是否允许省略、排序方向怎么写。第三步,拿示例代码跑一遍。PDF里每个函数都附了输入输出对照,我会在本地数据库里把示例原样执行一次,再把表名换成自己的业务表,验证结果是否符合预期。

这套流程看着简单,真正坚持做的人不多。很多人下载速查表之后直接塞进收藏夹,等用到时才翻,结果每次查到的函数都记不牢。我的习惯是每隔一两周挑一个不常用的函数,比如FIRST_VALUE或NTILE,找业务数据试一下,试完就记住了。

4. 窗口聚合与移动计算:SUM、AVG、COUNT配合frame的完整用法

排完名、取完相邻值,窗口函数最重的应用场景其实是聚合计算。SUM、AVG、COUNT这些函数加不加OVER,表现完全是两回事。速查表的聚合函数部分,核心就是在讲frame子句怎么控制计算范围。

4.1 累计求和与移动平均:frame边界决定计算范围

先看一个交易流水表的例子,同时算累计金额和3日移动平均:

SELECT trade_date, amount, SUM(amount) OVER ( ORDER BY trade_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_amount, AVG(amount) OVER ( ORDER BY trade_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS moving_avg_3 FROM daily_trade ORDER BY trade_date;

cumulative_amount这一列的含义是从第一天的交易额一直累加到当前行,因为frame起点是UNBOUNDED PRECEDING,终点是CURRENT ROW,每天一行数据。移动平均则用了ROWS BETWEEN 2 PRECEDING AND CURRENT ROW,意思是只取当前行往前数两行,一共三行做平均,这就是“3日移动平均”的实现。

frame边界的选择完全取决于业务口径。你要做的是累计值,起点就必须是UNBOUNDED PRECEDING;要做固定窗口的滑动平均值,起点就是n PRECEDING。速查表里把五种边界关键字全部列出来,并用小图标注了它们指向的位置,这张小图对新手来说比任何文字说明都直观。另外注意,frame的终点也完全可以超出当前行,比如用ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING算“从今天到未来的总和”,这在计算剩余额度时会用到。

我一般会建议团队把frame部分显式写全,不要依赖默认值。写过SUM(x) OVER (ORDER BY y)却忘了加frame的人,迟早会被默认的RANGE行为坑一次,具体坑法下面单独说。

4.2 ROWS与RANGE的区别:排序键重复时结果完全不同

这是整个窗口函数里最隐蔽的坑之一,也是速查表花了不少篇幅解释的内容。ROWS和RANGE都用来定义frame边界,但语义完全不同:ROWS严格按行号取数据,说2 PRECEDING就是物理上的前两行;RANGE按排序键的值取数据,排序键相同的行会被当成“同一行”一起纳入。

比如订单日期不是唯一的,同一天有好几笔订单。用SUM(amount) OVER (ORDER BY order_date RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)算累计值时,凡是order_date相同的行,frame都会把它们全部包含进来,每一行上算出的累计值都相同。而用ROWS版本时,每一行严格往前数行,每行的累计值都因为包含的行数不同而产生差异。

场景ROWS行为RANGE行为
排序键有重复严格按物理行数取把所有相同排序键的行一起纳入
排序键唯一两者结果一致两者结果一致
典型用途移动平均、固定窗口按日期累计、按值区间计算

判断自己该用哪个,只需要问一个问题:我要计算的范围是基于“物理行数”还是“排序键数值”?求3日移动平均,显然要固定取3行,用ROWS;按日期算累计值,想把同一天的数据视作一个整体,用RANGE也可以,但必须先确认自己知道这个语义。速查表的示例里两种写法都给了,我建议把两个结果并排执行一次,亲眼看一下差在哪,比背十遍理论都管用。

4.3 高频组合场景:占比、累计、连续登录的直接模板

窗口聚合在实际分析里用得最多的三个模板,速查表里都覆盖了,我在这里把它们的写法固定下来,拿来即用。

计算每个分类下的销售额占该分类总额的比例,以及截止到当前的累计占比:

SELECT category, order_date, sales_amount, SUM(sales_amount) OVER (PARTITION BY category) AS category_total, SUM(sales_amount) OVER ( PARTITION BY category ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sales, ROUND( SUM(sales_amount) OVER ( PARTITION BY category ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) * 100.0 / SUM(sales_amount) OVER (PARTITION BY category), 2 ) AS cumulative_pct FROM sales;

另一个高频场景是连续登录天数。思路是先用ROW_NUMBER()给每个用户按登录日期编号,再用“登录日期减编号”的差值分组——连续登录的日子差值相等,然后按差值计数:

WITH login_grouped AS ( SELECT user_id, login_date, DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY login_date ) DAY) AS group_id FROM user_login ) SELECT user_id, MIN(login_date) AS start_date, MAX(login_date) AS end_date, COUNT(*) AS continuous_days FROM login_grouped GROUP BY user_id, group_id;

这两个模板在很多分析报表里都能直接改表名复用。速查表里每个函数单独看都不难,难的是像这样把它们组合起来解决真实问题。我的经验是:先照着模板跑通,再逐段删减、修改参数,观察结果变化,很快就能理解每段代码的职责边界。

5. 窗口函数五个高频坑:从报错到结果翻车

窗口函数写起来快,排错可不容易。下面五条是我在实际项目中撞过、也在给团队做代码评审时反复见到的坑。速查表虽然不会直接告诉你怎么排查,但理解这些坑之后,再回头读速查表的语法说明,会有一种“原来那段警告是说这个”的豁然感。

5.1 坑一:WHERE子句不能直接过滤窗口函数的结果

现象:写SELECT ..., ROW_NUMBER() OVER (...) AS rn FROM t WHERE rn = 1,数据库直接报错,说窗口函数不允许出现在WHERE里。

原因:SQL的执行顺序里,WHERE在SELECT的表达式计算之前执行。窗口函数是在SELECT阶段计算的,等它算出rn,WHERE早执行完了,逻辑上就矛盾。

解决:用子查询或CTE包一层,先算窗口函数,再在外面过滤。

WITH ranked AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn FROM employee ) SELECT * FROM ranked WHERE rn = 1;

这是取“每个部门工资最高员工”的经典写法,把窗口函数放进CTE,外层再用普通条件过滤。从那以后我凡是看到窗口函数外面直接套WHERE的代码,第一反应就是先给提问的人画执行顺序图。

5.2 坑二:RANK跳号被业务方当成计算错误

现象:报表展示排名时,两个并列第1名后面直接是第3名,业务方一口咬定程序算错了,少了一个第2名。

原因:RANK()的语义就是跳号。两个并列第1占用1和2两个序号,所以下一个排名是3,这是标准行为,不是bug。

解决:先和业务方确认排名口径。如果强制要求排名连续,把RANK()换成DENSE_RANK(),它能输出1、1、2而不跳号。速查表里两个函数放在一起对比,就是为了让人选之前先想清楚。

5.3 坑三:忘了写ORDER BY,累计求和变成了组内求和

现象:想算“每个客户按时间累计的订单金额”,写了SUM(amount) OVER (PARTITION BY customer_id),结果每一行的累计值都一样,等于该客户全部订单总额。

原因:frame的默认范围与有没有ORDER BY强相关。没写ORDER BY时,窗口默认是整个分区;写了才能触发从分区起点到当前行的累计逻辑。

解决:算累计值时,写法必须是SUM(amount) OVER (PARTITION BY customer_id ORDER BY order_date),并且在排序键可能重复时加上显式的ROWS边界。速查表的语法部分明确标注了这个默认行为,我把它当成必背条目。

5.4 坑四:移动平均结果和Excel手工核对不一致

现象:用AVG算3日移动平均,拿Excel手工拉了一遍,发现两边对不上,差在日期相同的记录上。

原因:AVG(amount) OVER (ORDER BY trade_date)没写ROWS时用的是默认RANGE frame,日期相同的数据会被视为同一行一起纳入计算,导致一天多条订单时窗口里的行数超过了3行。

解决:移动平均这种对物理行数有严格要求的场景,必须显式写ROWS BETWEEN 2 PRECEDING AND CURRENT ROW,明确告诉数据库“按行取,不看值”。

5.5 坑五:COUNT(列)与COUNT(*)在窗口内对NULL的处理不同

现象:同一张表,COUNT(*) OVER (PARTITION BY dept_id)返回10,COUNT(remark) OVER (PARTITION BY dept_id)返回8,少了2条。

原因:COUNT(列)只统计该列非NULL的行,COUNT(*)统计所有行。窗口函数里的行为与普通聚合完全一致,remark列里恰好有2条NULL。

解决:统计行数时确认业务口径。想数“有多少条记录”,一律用COUNT(*);想数“有多少个非空值”,再用COUNT(列)。速查表在聚合函数说明里专门标注了这个问题,我最初没当回事,直到线上数对不上才后悔没早看。

6. 进阶用法:用WINDOW子句和CTE把窗口查询写成能维护的分析模板

窗口函数用多了就会发现,一段SQL里可能同时挂着四五个OVER,每个后面跟着相同的PARTITION BY和ORDER BY,改一个分区字段就得全文搜着改,容易漏。速查表没展开讲的WINDOW子句,恰好是解决这个问题的利器。

6.1 WINDOW子句:一个窗口定义到处复用

SELECT dept_id, emp_id, salary, SUM(salary) OVER w AS dept_total, AVG(salary) OVER w AS dept_avg, MAX(salary) OVER w AS dept_max FROM employee WINDOW w AS (PARTITION BY dept_id) ORDER BY dept_id, emp_id;

WINDOW w AS (PARTITION BY dept_id)定义了一个名为w的窗口,后面三个OVER子句都引用它。这样定义一次、多处使用的写法,比把PARTITION BY dept_id复制三遍清爽得多,改分区字段时只需要动WINDOW子句那一行。如果某个窗口还需要排序,就在定义里加上ORDER BY,但要注意:加了ORDER BY之后,所有引用该窗口的聚合函数的frame都会变成默认的RANGE累计模式,这时候要根据需要决定是否单独覆盖。

6.2 窗口函数与CTE组合:把复杂分析拆成可读步骤

CTE加窗口函数是我写分析SQL最顺手的组合,前面的连续登录模板已经演示过一例。核心思路是:一个CTE只做一件事,窗口函数在其中计算辅助列,外层查询负责过滤或二次加工。

取全公司每个部门工资排名前两名的员工,用两个CTE串联:

WITH ranked AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn FROM employee ), top2 AS ( SELECT * FROM ranked WHERE rn <= 2 ) SELECT * FROM top2;

每个CTE职责单一,排错时只需单独执行ranked那一段看结果,问题定位很快。我在做报表需求时基本都会把复杂逻辑拆成几步,比写几百行的单条SQL省心太多。

说到排错,我吃过一次亏:在某数据校验流程里,用连续登录模板统计用户活跃天数,有同事反馈结果比预期少了好几天,排查到最后发现是登录日期字段里混入了NULL,而COUNT(login_date)直接把NULL跳过去了。从那以后,我每次写完窗口函数都强制走一遍固定检查:单条SQL在3行以内的模拟数据上跑一遍,逐个核对输出值;凡是涉及COUNT的,先确认清楚要不要计NULL;涉及frame的,确认ROWS还是RANGE,每一步都拿速查表过一遍。这套流程看起来笨,但基本没再翻过车。希望这份速查表和学习路径,也能帮你少踩几个我已经踩过的坑。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 6:37:33

基于PJ85718DM与PIC18F96J65的嵌入式本地/远程温度监测方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 6:35:02

WebLogic安全自查:弱口令与CVE-2023-21839漏洞治理

1. 为什么我把WebLogic当成安全巡检的头号关注对象1.1 老牌中间件的两面性WebLogic在国内企业里部署量极大&#xff0c;金融、政务、制造、零售的核心系统里几乎都能看到它的身影。稳定性强、生态成熟&#xff0c;这是它长期被选型的原因。但硬币的另一面是&#xff1a;它代码量…

作者头像 李华
网站建设 2026/10/22 6:34:09

CityEngine 2023+ 零基础启动指南:绕过规则包加载失败与Java环境陷阱

简介&#xff1a;本资源是一份面向城市规划、数字孪生建模及GIS可视化初学者的CityEngine系统性入门笔记&#xff0c;聚焦ESRI公司推出的基于CGA规则的程序化建模方法&#xff0c;帮助用户快速掌握从语义建模思维到实际代码编写的完整路径。内容涵盖属性定义与分组&#xff08;…

作者头像 李华
网站建设 2026/10/22 6:33:52

Hector SLAM核心原理与源码推导:无里程计激光建图

做机器人定位建图的朋友&#xff0c;大概率都遇到过这个场景&#xff1a;手里没有轮式里程计&#xff0c;底盘要么是四足要么是无人机&#xff0c;轮子还会打滑。这时候很多人会想到 Hector SLAM——它不需要里程计&#xff0c;单靠激光雷达就能在二维栅格地图上把位置估计出来…

作者头像 李华
网站建设 2026/10/22 6:33:32

PHU图像预处理协议栈:工业视觉中跨设备一致性的技术实现

简介&#xff1a;本资源是面向4G/5G无线网络优化工程师、网规技术人员及华为PHU路测实操人员的专业培训文档&#xff0c;聚焦PHU-Smart手机路测工具与GC云平台的全流程协同应用&#xff0c;解决外场测试效率低、设备投入大、数据回传慢等实际痛点。文档完整覆盖GC平台账号开通、…

作者头像 李华
网站建设 2026/10/22 6:32:41

Rust构建的离线语音AI Agent:舰载级系统交互实践

1. 这不是“语音助手”&#xff0c;而是把《星际迷航》的“企业号主计算机”从幻想拉进终端里你有没有试过对着电脑说一句“调出瓦肯星地质图”&#xff0c;然后屏幕真的滑出一张带经纬网格与火山标注的3D球体&#xff1f;或者问“斯波克的生命体征如何”&#xff0c;下一秒就弹…

作者头像 李华