1. 聚合函数先打个底1.1 五个最常用的聚合函数你真的用对了吗MySQL 里的聚合函数说白了就是“把多行数据揉成一行结果”的函数。平时工作中最常见的无非是 COUNT、SUM、AVG、MIN、MAX 这五个但它们各自的细节坑并不少。先说 COUNT。很多人写统计总数时随手就是COUNT(*)这没问题它统计的是符合条件的所有行数包括整行都是 NULL 的行。但如果你写成COUNT(salary)那就只统计 salary 字段非 NULL 的行数了。这个区别在字段允许为 NULL 的表中特别容易翻车后面我在坑点部分会专门展开。SUM 和 AVG 比较好理解但也有一个共性陷阱如果参与计算的列里有 NULL 值MySQL 的 SUM、AVG 会直接忽略 NULL而不是把 NULL 当成 0。举个例子一个订单明细表里退款金额字段很多行是 NULL你直接SUM(refund_amount)结果其实是“非 NULL 退款金额的合计”不是“默认 0 的合计”。如果业务上 NULL 表示“没发生退款”那预期应该是 0直接 SUM 也没毛病但如果你的数据入库时没做默认值处理NULL 和 0 混在一堆统计结果就可能比预期小排查还特别费劲。MIN 和 MAX 多数时候很直观但需要注意它们在不同数据类型上的表现对字符串取 MIN/MAX是按字符串排序规则来的不是按“看起来像数字”的顺序对日期时间类型直接取 MAX 就是算“最近一次”这在取用户最后登录时间时很实用。来个最简单的例子还是用下面这个员工表CREATE TABLE emp ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), dept VARCHAR(20), salary DECIMAL(10, 2) ); INSERT INTO emp (name, dept, salary) VALUES (张三, 技术部, 12000), (李四, 技术部, 13500), (王五, 技术部, 11000), (赵六, 运营部, 9500), (孙七, 运营部, 10200), (周八, 运营部, 8900), (吴九, 产品部, 14500), (郑十, 产品部, 15000);基础聚合随便一写就是这样SELECT COUNT(*) AS 员工数, SUM(salary) AS 总工资, AVG(salary) AS 平均工资, MIN(salary) AS 最低工资, MAX(salary) AS 最高工资 FROM emp;这个结果集只有一行但已经把这些函数的脾性全暴露出来了。AVG 在 MySQL 里默认就是按照浮点或 DECIMAL 精度算出的小数不会自动四舍五入成整数。你如果业务上需要“人均工资保留两位小数”要么在查询结果里套 ROUND要么建表时把字段类型设计成 DECIMAL(10, 2) 并在统计时注意返回精度。1.2 GROUP BY 分组聚合的发动机聚合函数不配 GROUP BY那只是“全局统计”一旦配上 GROUP BY聚合函数才会真正体现出“分部门、分城市、分渠道”的价值。它的逻辑很像 Excel 里的透视表先按指定列把数据切片然后在每个切片里执行聚合。常见写法是这样SELECT dept, COUNT(*) AS cnt, AVG(salary) AS avg_sal FROM emp GROUP BY dept;这里有个非常关键的执行顺序问题WHERE 是先过滤行再分组HAVING 是先分组再过滤组。所以如果你想查“技术部里工资大于 10000 的员工有多少”应该把salary 10000放进 WHERE而不是 HAVING。但是如果你想查“平均工资大于 10000 的部门有哪些”那必须在 HAVING 里写AVG(salary) 10000因为 WHERE 不能使用聚合函数的计算结果。SELECT dept, AVG(salary) AS avg_sal FROM emp GROUP BY dept HAVING AVG(salary) 10000;另一个容易踩的坑是 ONLY_FULL_GROUP_BY 模式。MySQL 5.7 之后默认开启了这个 SQL 模式它要求出现在 SELECT 列表里的普通列必须要么被 GROUP BY 包含要么被聚合函数包住。不然会直接报错。这其实是好事能逼你在写 SQL 时想清楚“非聚合列”到底取哪一行。如果业务上确实想取“组内第一个值”或“组内某个特殊行”更稳的做法是配合窗口函数或子查询而不是去关闭这个模式。GROUP BY 还支持多列比如按部门和城市统计GROUP BY dept, city。它的分组粒度会更细等于先按 dept 分成大组再在大组里按 city 分成小组所有聚合都是基于最小分组的。1.3 GROUP_CONCAT 及其他冷门聚合函数除了常规五件套GROUP_CONCAT 在我实际工作中出镜率也很高。它能把组内多个字段值拼成一个字符串比如查“每个部门都有哪些员工”一条 SQL 就出来了SELECT dept, GROUP_CONCAT(name SEPARATOR 、) AS emp_names FROM emp GROUP BY dept;默认分隔符是逗号想改可以用SEPARATOR关键字。更实用的是它支持在拼接前排序比如按工资从高到低拼接SELECT dept, GROUP_CONCAT(name ORDER BY salary DESC SEPARATOR 、) AS emp_names FROM emp GROUP BY dept;这个函数在生成报表、导出数据、处理一对多关系时能省掉大量代码但要注意它有长度限制默认值是 1024 字节超过了会被截断。如果需要拼很长文本可以调group_concat_max_len系统变量。MySQL 里还有几个不那么常用但值得知道的聚合函数BIT_AND、BIT_OR、BIT_XOR做位运算聚合适合处理权限位、开关位这种场景STDDEV和VAR_POP/VAR_SAMP做标准差和方差统计数据分析场景能用上。这些不常用但面试问到“MySQL 聚合函数有哪些”时点名提到它们能体现你的储备不是背出来的。2. 窗口函数不折叠行的“分组计算”2.1 窗口函数到底解决了什么问题传统聚合函数最大的“毛病”是折叠行。比如你按部门统计平均工资部门里每个员工的原始行数据就没了只能看到一个部门的汇总结果。可实际业务里我经常遇到这样的需求既要看到员工自己的工资又要知道所在部门的平均工资甚至还想算“员工工资占部门总工资的比例”。如果用普通聚合函数你得先写个子查询算部门统计再 JOIN 回去麻烦且性能一般。窗口函数就是为这种场景设计的它既能像 GROUP BY 一样按某个维度分组又不会把多行压缩成一行每一行原样保留旁边多出一列计算结果。窗口函数的核心语法是函数名 OVER (PARTITION BY 列 ORDER BY 列)PARTITION BY相当于分组叫“分区”它定义了窗口范围ORDER BY在窗口函数里不单单是排序它还决定了窗口计算的顺序和累计逻辑这一点特别容易和普通 ORDER BY 混淆。比如SUM(salary) OVER (PARTITION BY dept ORDER BY salary)这个 SUM 是“截至当前行的累计和”不是“整个部门的总和”。如果你只想要部门总和一定不要加 ORDER BYSELECT name, dept, salary, SUM(salary) OVER (PARTITION BY dept) AS dept_total FROM emp;执行结果里同部门每一行显示的 dept_total 都一样这就是“部门总工资”。如果你脑抽加了ORDER BY salary结果就会变成累计求和同部门每个员工看到的数都不相同这个区别极其关键。2.2 排名三兄弟ROW_NUMBER、RANK、DENSE_RANK窗口函数里有三个函数几乎每天都会用上就是排名三兄弟。ROW_NUMBER()不管有没有并列依次给每一行分配唯一的序号1、2、3、4……RANK()有并列时会出现跳号比如两个并列第 1下一个就是第 3。DENSE_RANK()有并列时不会跳号两个第 1 之后下一个还是第 2。员工表里按部门内部工资排名SELECT name, dept, salary, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS row_num, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rk, DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dense_rk FROM emp;如果同一个部门里有两个人的工资正好都是 13500那么 ROW_NUMBER 会硬分出 1 和 2RANK 会给出 1 和 1下一个名次是 3DENSE_RANK 也会给出 1 和 1但下一个名次是 2。这个细微差别在做竞赛排行榜、销售榜单时直接决定业务口径。比如“并列第二算不算第二”如果是“取前两名并列只算两个名额”用 ROW_NUMBER如果是“并列都应该入选”就得用 RANK 或 DENSE_RANK具体再看要不要跳号。NTILE(n)也是灵活度很高的一个窗口函数它会把分区里的行尽量均匀地分成 n 组然后告诉你每行落在第几组。这个在“按排名分桶”比如把用户按消费金额分成高、中、低三档时非常方便。2.3 LAG、LEAD 和滑动窗口函数除了排名窗口函数另一个高频用法是访问相邻行。LAG(列, n)取当前行往前数第 n 行的值LEAD(列, n)取往后数第 n 行的值。这个能力用来算环比、同比、对比上一笔订单都特别舒服。比如有一张每日销售额表CREATE TABLE daily_sales ( sale_date DATE PRIMARY KEY, amount DECIMAL(10, 2) ); INSERT INTO daily_sales (sale_date, amount) VALUES (2025-01-01, 1200.00), (2025-01-02, 1500.00), (2025-01-03, 1300.00), (2025-01-04, 1700.00);计算每日销售额和它前一天的差值SELECT sale_date, amount, LAG(amount, 1) OVER (ORDER BY sale_date) AS prev_amount, amount - LAG(amount, 1) OVER (ORDER BY sale_date) AS diff FROM daily_sales ORDER BY sale_date;这里窗口里的 ORDER BY 决定了 LAG 的方向。如果不写 ORDER BY那 LAG 就不知道“往前数”到底按什么顺序所以这种场景下 ORDER BY 不是可选项而是必须项。滑动窗口则更复杂一点它通过ROWS或RANGE子句来控制窗口的行范围常见写法是SELECT sale_date, amount, AVG(amount) OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg FROM daily_sales ORDER BY sale_date;这算的是“当前行以及前两行”的移动平均常用于平滑曲线图、过滤数据噪声。注意ROWS BETWEEN ... AND ...的语法可以定义当前行之前多少行和之后多少行。如果不写帧定义MySQL 会根据是否存在 ORDER BY 给出默认窗口有 ORDER BY 时默认是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW这是累计语义没有 ORDER BY 时才是整个分区这个默认行为很多人记不住索性每次写窗口时都把自己想要的边界写清楚才是好习惯。3. 数学函数SQL 里的科学计算器3.1 常用数学函数快速过一遍MySQL 的数学函数不像聚合和窗口那样“高深”但胜在数量多很多人在用到的时候才搜其实提前掌握能省不少事。绝对值函数ABS(-10)返回 10不用多想。取整函数有两个容易混CEIL/CEILING向上取整FLOOR向下取整。CEIL(3.2)结果是 4FLOOR(3.8)结果是 3。注意它们都不做四舍五入也不关心正负号的方向CEIL(-3.2)结果是 -3别搞反了。ROUND是最常用的四舍五入函数支持指定小数位ROUND(3.14159, 2)返回 3.14ROUND(3.145, 2)返回 3.15。这里有个隐蔽的坑MySQL 的 ROUND 对小数位的处理依赖浮点数的二进制表示某些值会出现诡异的舍入结果比如ROUND(2.675, 2)在某些版本下可能返回 2.67 而不是 2.68。这涉及浮点精度问题后面单开一节讲。TRUNCATE和 ROUND 长得挺像但它是直接截断TRUNCATE(3.14159, 2)返回 3.14不管第三位是 4 还是 5直接砍掉不做舍入。如果你处理的是金额明细要求“分以下直接舍去”用 TRUNCATE 而不是 ROUND。求余数用MOD(10, 3)返回 1也可以直接写10 % 3效果一样。幂运算和开方分别是POWER(2, 10)返回 1024SQRT(9)返回 3。SIGN(-5)返回 -1SIGN(0)返回 0SIGN(5)返回 1判断正负数很顺手。RAND()返回 0 到 1 之间的随机数可以带种子参数RAND(100)每次执行结果相同适合调试可复现的随机场景。3.2 ROUND 精度里藏着的浮点坑浮点数精度问题在 MySQL 里特别容易翻车。原因很本质计算机里很多十进制小数没法用二进制精确表示比如 0.675 在二进制里是个无限小数存储时被近似了ROUND 再按照这个近似值做舍入结果就会偶尔“离谱”。我实测过的一个经典案例是ROUND(2.675, 2)在很多 MySQL 版本里返回 2.67因为这个数实际存储的浮点值比 2.675 略小一点点。解决方案有两个一是把运算的字段类型定义为 DECIMALDECIMAL 是定点数不存在浮点误差ROUND(CAST(2.675 AS DECIMAL(10, 3)), 2)就正常返回 2.68二是允许接受极小误差在很苛刻的金额计算里用浮点本身就是错误源头。还有一点要注意MySQL 的 ROUND 和很多程序设计语言的“四舍五入”规则并不完全一样。传统意义上的四舍五入是 0.5 就进位但某些语言用的是“银行家舍入”round half to evenMySQL 默认行为更接近于“离零更远的方向舍入”。所以跨语言核对金额时别假设规则相同最好以数据库的最终计算结果为准或者统一在应用层计算。3.3 数学函数在业务里的常见组合数学函数的价值不会单独体现一定要和业务场景结合。比如订单金额里有折扣和税费计算实付金额SELECT order_id, ROUND(original_amount * 0.8, 2) AS discounted_amount, TRUNCATE(original_amount * 0.8, 2) AS actual_paid_amount FROM orders;折扣通常要四舍五入到分但如果业务方要求“抹零”则用 TRUNCATE。随机抽样是另一个高频场景。从用户表里随机抽 5 个用户做活动测试大家大概率会写SELECT * FROM users ORDER BY RAND() LIMIT 5;这个写法数据量小完全没问题但如果表有几百万行ORDER BY RAND()会产生临时表和全表排序性能很差。可以改成先取主键范围再用 RAND 在主键区间里随机选几个 ID性能能提升几个数量级。还有地理距离计算。如果只做粗略预估可以用:SELECT name, SQRT(POWER((lng1 - lng2) * 111000, 2) POWER((lat1 - lat2) * 111000, 2)) AS distance_m FROM places;纬度方向上每度大约 111 公里经度方向上会随纬度变化如果对精度要求很高就别偷懒直接用 Haversine 公式和三角函数MySQL 也提供了ACOS、COS、SIN、RADIANS这些函数。数学函数单个都很简单组合起来解决实际问题才是价值所在。4. 三军联合作战一个完整案例带你把函数揉进真实业务4.1 场景一按部门计算员工工资占比假设现在公司要让每个员工看到自己在部门内的工资排名和占比这是聚合函数、窗口函数、数学函数三合一的经典场景。员工表还是前面那张 emp 表。需求拆开来是这样的每个员工的工资在部门内的排名每个员工的工资占部门总工资的百分比百分比保留两位小数普通聚合思路先按部门分组算总工资再 JOIN 回员工表最后用 员工工资 / 部门总工资 算占比。这样的 SQL 要写两层子查询看起来不优雅。窗口函数一条 SQL 就能解决SELECT name, dept, salary, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_rank, ROUND( salary / SUM(salary) OVER (PARTITION BY dept) * 100, 2 ) AS salary_percent FROM emp ORDER BY dept, salary DESC;这里的SUM(salary) OVER (PARTITION BY dept)返回的是部门总工资同一部门内每一行都一样所以每个员工都能拿着这个值计算自己的占比。RANK 用来做部门内排名处理并列时更符合“薪酬排名”业务习惯。最后用 ROUND 把占比保留两位小数。如果这时候需求再细化一点只想看“部门内工资占比超过 20% 的员工”你会发现 WHERE 和 HAVING 都没法直接用因为窗口函数计算出的结果在 SELECT 阶段才产生。正确做法是套一层子查询SELECT * FROM ( SELECT name, dept, salary, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_rank, ROUND(salary / SUM(salary) OVER (PARTITION BY dept) * 100, 2) AS salary_percent FROM emp ) t WHERE salary_percent 20;这种“先算窗口再过滤结果”的模式在复杂报表里极其常见请务必记住窗口函数不能直接出现在 WHERE 子句里。4.2 场景二销售订单的环比增长和移动平均再来看一段销售分析需求。有一张订单表记录每天的销售额现在需要按天算出销售额环比增长率和三日移动平均。表结构我们前面建过 daily_sales现在往里面插多一点数据再演示INSERT INTO daily_sales (sale_date, amount) VALUES (2025-01-05, 2000.00), (2025-01-06, 1800.00), (2025-01-07, 2400.00), (2025-01-08, 2600.00);环比增长率的定义是(当天销售额 - 前一天销售额) / 前一天销售额 × 100%。这里用 LAG 很顺手SELECT sale_date, amount, LAG(amount, 1) OVER (ORDER BY sale_date) AS prev_amount, ROUND( (amount - LAG(amount, 1) OVER (ORDER BY sale_date)) / LAG(amount, 1) OVER (ORDER BY sale_date) * 100, 2 ) AS growth_rate, ROUND( AVG(amount) OVER ( ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ), 2 ) AS moving_avg_3 FROM daily_sales ORDER BY sale_date;第一天的 prev_amount 是 NULLgrowth_rate 也自然是 NULL在报表里显示为空这符合业务预期不用特意处理。这个查询同时用到了 LAG、窗口函数里的 AVG、ROWS BETWEEN 滑动窗口、ROUND 和小数精确控制。窗口函数加数学函数配合聚合函数做时间序列分析是数据分析岗最常用的技能组合之一。4.3 场景三各种分组 TopN 查询TopN 查询是窗口函数最经典的应用场景。需求找出每个部门工资最高的前 2 名员工。如果不用窗口函数你得写各种带有“相关子查询”的复杂 SQL还容易算错。使用 ROW_NUMBER 很简单SELECT name, dept, salary FROM ( SELECT name, dept, salary, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn FROM emp ) t WHERE rn 2 ORDER BY dept, salary DESC;注意这里子查询里排序是按工资降序然后外部再按部门排序目的是保持输出顺序好读。实际业务中如果遇到“取的 TopN 中工资并列的都要”就把 ROW_NUMBER 换成 RANK 或 DENSE_RANK并根据业务口径决定是否允许跳号。TopN 和前面员工占比、环比增长一样本质思路都是“先通过窗口函数生成辅助列再用子查询做过滤或二次加工”。把这个模式吃透你大概也就掌握了 70% 的窗口函数实战场景。5. 这三个函数最容易踩的坑我挨个帮你趟一遍5.1 COUNT(*) 与 COUNT(列) 的结果不同这是聚合函数里翻车率最高的一个问题。COUNT(*) 统计的是行数不管这一行是不是全 NULLCOUNT(列名) 统计的是该列非 NULL 的行数。之前有个朋友跑数据业务上要统计“这个月下单用户数”他直接写了COUNT(user_id)结果发现比COUNT(*)少了很多。排查半天发现是用户表里历史数据有一批 user_id 是 NULL 的记录这些记录根本不是有效用户但又占着行。实际上在这个需求场景里COUNT(user_id)反而是对的因为它会自动忽略空用户。关键是写 SQL 前你得想清楚你要的是“所有行数”还是“某个字段有值的行数”。统计口径一旦定错后面所有报表都会跟着错。5.2 SUM、AVG 遇到 NULL 不等于 0SUM 和 AVG 对 NULL 的处理是直接跳过既不报错也不把它当 0 计算。这个机制天然合理但它会带来一个反直觉的结果如果参与聚合的全部都是 NULLAVG 返回的是 NULL而不是 0。比如订单表里有 5 单退款金额都是 NULL你执行AVG(refund_amount)得到的是 NULL前端展示出来就是个空值用户看着像 bug。稳妥的做法是对结果做一次空值兜底SELECT IFNULL(AVG(refund_amount), 0) AS avg_refund FROM orders;或者用COALESCE(AVG(refund_amount), 0)语义一样但 COALESCE 是标准 SQL 写法可读性和兼容性更好。5.3 GROUP BY 导致 ONLY_FULL_GROUP_BY 报错MySQL 5.7 以上默认开启 ONLY_FULL_GROUP_BY 模式最典型的报错信息是Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column ...意思是 SELECT 后面的普通列没有出现在 GROUP BY 里也没有被聚合函数包裹。解决方式只有两个一是把你真正要展示的列加进 GROUP BY二是用合适的方式聚合。千万不要遇到报错就关掉这个模式除非你清楚地知道自己在干什么。关掉之后 MySQL 会从分组结果中随机选一行不同版本、不同执行计划可能选出不同的值这种隐藏的不确定性比报错可怕得多。5.4 窗口函数不能在 WHERE 和 HAVING 中直接使用窗口函数是在查询执行到 SELECT 阶段才计算的所以 WHERE、HAVING 虽然在语义上“更早”执行但在 SQL 语法层面都没法直接引用窗口函数的结果。我见过不少初级同事写这种 SQL-- 错误的写法 SELECT name, dept, salary, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rk FROM emp WHERE rk 1;这会在解析阶段直接报错。正确做法是把窗口函数查询放到子查询里然后在外层过滤。前面 TopN 的例子里就是用这个模式。这个习惯一定要养成不然等你写复杂嵌套查询时会反复被这种语法错误卡住。5.5 ROUND、TRUNCATE 和 DECIMAL 别混用数学函数的坑集中在精度和类型。ROUND 返回的结果类型跟着入参走如果入参是 FLOAT结果可能带浮点尾数如果入参是 DECIMAL结果也是 DECIMAL。所以在金额计算时建议把列类型设计成 DECIMAL计算函数也统一用 ROUND。还有一个小细节MOD函数对 DECIMAL 也有效但如果你的需求是“判断是否为偶数”用MOD(id, 2) 0没问题但 id 一旦超过某些精度范围浮点误差也可能钻进来。别嫌啰嗦数据库里的每一个看起来“差不多”的结果最后都可能成为报表里对不上的那几毛钱。5.6 窗口函数的 ORDER BY 和普通 ORDER BY 语义不同这个坑我放在最后说因为它最难发现。普通查询的 ORDER BY 只影响最终结果的展示顺序。但窗口函数里的 ORDER BY 会直接影响计算结果。同样是滑动求和SUM(salary) OVER (PARTITION BY dept) -- 部门总工资每行一样 SUM(salary) OVER (PARTITION BY dept ORDER BY salary) -- 截至当前行的累计工资 SUM(salary) OVER (PARTITION BY dept ORDER BY salary DESC) -- 从当前行到末尾的逆序累计三行 SQL 只差一个 ORDER BY结果天差地别。如果你不是故意要“累计”“移动”语义就千万别在窗口函数里随手加 ORDER BY。反过来如果你要算同比、环比、移动平均又必须确保 ORDER BY 字段和业务上的时间顺序完全一致否则算出来的 LAG 会指向完全不相干的行。6. 我对这三个函数使用的几点体感最后说点我自己在实际项目里的体感。聚合函数看着简单却是很多 SQL 性能问题的起点。比如COUNT(DISTINCT 列)在数据量大时会触发去重排序性能成本很高如果业务允许近似值可以考虑用专门的统计方案又比如 GROUP BY 字段如果没建索引临时表可能直接落在磁盘上查询会突然慢一个量级。这些都属于“知道写法只是入门知道为什么慢才是进阶”的问题。窗口函数在 MySQL 8.0 之前是不支持的如果你还在维护 5.7 的老库很多排名和环比逻辑只能靠变量模拟又慢又绕。升级到 8.0 之后窗口函数提供了很大便利。不过窗口函数也别滥用遇到“每个分组取前几条”这种需求用窗口函数没问题但如果只是简单分组统计用普通聚合就够了窗口函数通常不会减少扫描成本还容易让执行计划变重。数学函数单个都很轻但组合起来时要注意每个函数的返回类型。比如 ROUND 以后的结果继续参与除法如果不注意用 CAST 或直接依赖 DECIMAL 列最终结果就可能出现精度漂移。数据领域常说“垃圾进垃圾出”在 MySQL 的数值计算里应该改成“精度进精度出”。本篇从聚合函数的分组逻辑到窗口函数不折叠行的计算方式再到数学函数在业务里的组合用法基本把 MySQL 里和“计算”相关的常用函数拉通了一遍。下一篇有思路的话我想接着聊时间日期函数和流程控制函数这两个在实际报表里和聚合、窗口配合得也相当紧密。
企业数字化 ERP 产品动态
相关推荐
C++链表实现栈:从原理到代码,彻底搞懂后进先出 说实话,很多人学数据结构的第一个坎,就卡在栈这个看似简单的结构上。上课听老师讲"后进先出"觉得什么都懂了,真让自己用代码实现,却连节点怎么定义、指针怎么指都理不清。我自己当年学 C 链表实现栈的时候,也… · 2026/9/24 19:38:55
密码管理器迁移指南:从浏览器记住密码到 Bitwarden 密码管理器迁移指南:从浏览器记住密码到 Bitwarden
「所有网站用同一个密码」是数字时代最危险的习惯。Bitwarden(GPL-3)是迁移成本最低的密码管理方案:全平台、端到端加密、免费版够用。
一、为什么浏览器记住密码不够用
不跨… · 2026/9/24 19:38:55
C++实现链表栈:从原理到完整代码与内存管理实战 栈大概是数据结构里最“老实”的一个结构了——你放进去一叠元素,它只按完全相反的顺序给你吐出来。后进先出的规则听起来简单,但真要在C里用链表把它实现出来,却能把指针、内存管理、拷贝控制这些C核心基本功全都串一遍。尤其是很多同学数组… · 2026/9/24 19:38:55
Filez AI文档中台V9:企业文档智能化的设计与实战 做企业文档和知识管理这些年,我越来越确认一个判断:大模型真正值钱的落地场景,不在聊天,而在文档。Filez AI文档中台V9这样的产品,解决的正是企业文档从“存起来”到“用起来”再到“管起来”的最后一公里。这篇文章我… · 2026/9/24 20:20:29
腾讯数字人+大模型知识引擎:企业智能问答系统架构与落地实践 1. 从数字人到知识引擎:这套产品组合到底在解决什么问题第一次接触腾讯这套数字人加知识引擎的组合,是在一个企业智能客服的升级项目里。当时客户提的需求很直接:现有的客服系统回答太机械,用户问三句就转人工,人工成本… · 2026/9/24 20:20:29
AI绘画中文提示词横评:六款工具真实理解力与提效技巧 我用一个周末,把目前市面上能直接写中文提示词的AI作图工具翻出来挨个测了一遍。测的不是那种“能跑就行”的程度,而是拿中文里的成语、古诗词、长定语、口语化描述、甚至带点“网络梗”的提示词去怼,专门看谁翻车、谁还能接得住。这篇文章就… · 2026/9/24 20:20:29
本地AI助手 WorkBuddy 实战:从模型配置到自动化工作流全指南 从 WorkBuddy 聊起:本地 AI 助手到底怎么用?一篇案例拆解 可抄作业的上手指南上个月清理办公电脑,我发现自己装了一堆 AI 客户端:有对接云端大模型的、有专门写代码的、有搞知识库问答的,每个都要单独配置、单独记 AP… · 2026/9/24 20:20:29
BugKu——备份是个好习惯 一、题目二、工具dirsearch下载方法:pip install dirsearch三、方法打开网站,一串数字。看题目,应该跟备份有关。用dirsearch扫一下,看看有没有bak。dirsearch -u http://160.202.254.160:18821/扫到一个绿色有效文件,… · 2026/9/24 20:20:29
工厂总装车间感应照明方案:总线智能化节能控制系统 按需照明 总装车间照明改造:总线方案如何实现工位级感应与智能化节能总装车间是汽车工厂中面积最大、工位最密集的车间。装配工位照度要求300-600lx,关键操作面不低于600Lx。但总装车间照明改造的核心矛盾不在于“够不够亮”,而在于能不能按需亮。从招… · 2026/9/24 20:20:23
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44