news 2026/10/13 4:30:19

MySQL CASE WHEN 用法详解:从条件判断到复杂查询优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL CASE WHEN 用法详解:从条件判断到复杂查询优化

你写SQL的时候,是不是经常碰到"要根据某个字段的值,决定展示成什么内容"这种需求?比如查订单状态,数据库里存的是数字0、1、2,但业务方要看"待付款""已发货""已完成";又比如统计报表,要把各省份销售数据合并成大区;再比如某张明细表里男女性别要用中文显示而不是M/F。以前我老用 UPDATE 一遍数据或者在前端代码里写一长串 if-else 去翻译,直到被同事的代码 Review 教育了一次,才发现 MySQL 里一个被低估的语法——CASE WHEN,这些场景一条 SQL 就全解决了。

这篇文章我会把 CASE WHEN 的两种写法、和 IF() 的区别、能做哪些进阶操作、以及我在实际项目里踩过的坑一次说清楚。不管你是刚学会写 SELECT 的新手,还是已经写了几年 SQL 想查漏补缺的老手,这篇都应该能让你在下次写复杂查询的时候多一点底气。

1. CASE WHEN 的核心用法与两种标准写法

1.1 简单 CASE 表达式:等值判断的场景

先看最简单的一种,语法长这样:

CASE column_name WHEN value1 THEN result1 WHEN value2 THEN result2 ELSE result_default END

这种写法在做"字段等于某值时转换"的场景最直观。比如订单表里 status 字段存的是 tinyint,业务定义 0 待支付、1 已支付、2 已发货、3 已完成、4 已取消,直接写成下面这样就够了:

SELECT order_id, CASE order_status WHEN 0 THEN '待支付' WHEN 1 THEN '已支付' WHEN 2 THEN '已发货' WHEN 3 THEN '已完成' WHEN 4 THEN '已取消' ELSE '未知状态' END AS status_desc FROM orders;

注意简单 CASE 表达式里的 WHEN 后面跟的是具体的值,并且只能做等值判断,也就是 MySQL 会在内部把它转译成CASE WHEN order_status = 0 THEN ...这种形式。所以如果判断条件是"大于""小于""非空""范围判断",简单 CASE 就无能为力了。

1.2 搜索式 CASE 表达式:条件判断才是完全体

绝大多数场景我推荐用搜索式 CASE,语法是:

CASE WHEN condition1 THEN result1 WHEN condition2 THEN result2 ELSE result_default END

注意是 CASE 后面直接跟 WHEN,没有字段名。每个 WHEN 后面是一个完整的逻辑判断表达式,支持=、>、<、<>、BETWEEN、IN、LIKE、IS NULL等等。比如上面的订单状态,如果我想把"已支付"和"已发货"一起归类为"进行中",用搜索式就能直接实现:

SELECT order_id, CASE WHEN order_status IN (2, 3) THEN '进行中' WHEN order_status = 0 THEN '待支付' WHEN order_status = 1 THEN '待收货' WHEN order_status = 4 THEN '已取消' ELSE '未知' END AS order_phase FROM orders;

这才是 CASE WHEN 真正强大的地方——它不仅仅是个"字典翻译器",更是一个灵活的行级条件逻辑引擎。

1.3 两种写法的性能与求值顺序陷阱

很多人以为简单 CASE 和搜索式 CASE 性能有差异,其实在 MySQL 内部,简单写法会被改写成搜索写法来执行,所以执行计划上几乎没有差别。真正需要注意的是求值顺序:CASE WHEN 会从上到下依次判断条件,一旦某个 WHEN 条件成立,后续的 WHEN 分支就不再执行了。

这个特性带来一个非常隐蔽的坑。比如我见过有人写这种逻辑:

SELECT CASE WHEN price > 100 THEN '高消费' WHEN price > 50 THEN '中消费' ELSE '低消费' END AS level FROM products;

这个没问题,因为条件是有序的。但如果反过来写:

CASE WHEN price > 50 THEN '中消费' WHEN price > 100 THEN '高消费' ELSE '低消费' END

价格 200 的商品会命中第一个price > 50,直接返回"中消费",而"高消费"这个分支永远没机会执行。这种逻辑错误 SQL 不会报错,但数据完全错了,而且特别难排查。我的经验是,写 CASE WHEN 时要像写路由表一样,优先把最严格、最具体的条件放在前面。

注意:ELSE 分支不要省略。如果所有 WHEN 都未命中且没有 ELSE,CASE 表达式会返回 NULL。NULL 参与后续计算(比如求和、拼接)会带来意想不到的结果,所以哪怕 ELSE 值为 '其他' 或 0,也要显式写上。

2. CASE WHEN 与同类函数的对比选型

2.1 CASE WHEN 比 IF()、IFNULL()、NULLIF() 灵活在哪

MySQL 里做条件判断的函数不少,IF()用起来确实短平快:

SELECT IF(score >= 60, '及格', '不及格') FROM student_scores;

但 IF() 有两个明显瓶颈:第一,IF() 本质上只是二选一的分支,想判断三档四档就得嵌套,一嵌套可读性立刻崩塌;第二,IF() 返回的是单个值,没法在 SET 语句里同时更新多个字段。CASE WHEN 则可以在一个表达式里完成多分支判断,也可以在 UPDATE 语句里根据不同条件更新同一列,灵活度完全不是一个级别。

IFNULL()和NULLIF()就是更窄的专用函数了。前者只在处理"字段为空给默认值"时用,后者在两个参数相等时返回 NULL,一般做防除零用。它们和 CASE WHEN 不是替代关系,但在通用性上,CASE WHEN 是那个"兜底万能工具"。

2.2 聚合函数中的条件统计:CASE WHEN 与 SUM 的组合

这是我个人日常使用频率最高的场景。要统计一张订单表里不同状态订单的数量和金额占比,传统写法要分别跑多个查询再合并,但在聚合函数里直接套 CASE WHEN,一个查询就能拿到全部指标:

SELECT COUNT(*) AS total_orders, SUM(CASE WHEN order_status = 0 THEN 1 ELSE 0 END) AS pending_cnt, SUM(CASE WHEN order_status = 2 THEN 1 ELSE 0 END) AS shipped_cnt, ROUND( SUM(CASE WHEN order_status = 2 THEN order_amount ELSE 0 END) / NULLIF(SUM(order_amount), 0) * 100, 2 ) AS shipped_amount_pct FROM orders WHERE created_at >= '2024-01-01';

这里有两个细节值得展开说。第一个是SUM(CASE WHEN ... THEN 1 ELSE 0 END)的写法本质上是"把符合条件的行标记为1,然后求和",这比COUNT(CASE WHEN ... THEN 1 END)语义更清晰,因为 COUNT 会忽略 NULL,如果 THEN 后面不写 1 而写 NULL,计数就会出问题。第二个是求占比时一定要处理除零,我用NULLIF(SUM(order_amount), 0)把除数为 0 的情况转成 NULL,避免 SQL 直接报除法错误。

2.3 用 CASE WHEN 做行转列的替代方案

行转列(Pivot)是 CASE WHEN 最经典的高级应用。比如下面这种记录学生各科成绩的表:

-- student_id, subject, score -- 1, '语文', 90 -- 1, '数学', 95 -- 1, '英语', 88

需要输出一行带三列分数的宽表,直接这么写:

SELECT student_id, MAX(CASE WHEN subject = '语文' THEN score END) AS chinese_score, MAX(CASE WHEN subject = '数学' THEN score END) AS math_score, MAX(CASE WHEN subject = '英语' THEN score END) AS english_score FROM student_scores GROUP BY student_id;

注意这里用了MAX()而不是SUM(),核心原因是为了配合 GROUP BY。由于同一个 (student_id, subject) 组合在表里只有一条记录,CASE WHEN 命中的时候返回分数,未命中的时候返回 NULL,聚合函数 MIN 和 MAX 都会自动忽略 NULL,所以取到的是唯一的那条非空值。这个写法比自连接简洁太多,而且扩展性很好——加一科就多加一个 MAX(CASE WHEN ...) 列。

3. 实际业务场景中的 CASE WHEN 组合技

3.1 用 CASE WHEN 做日期维度的分组统计

运营同学最常问的一个问题是:"这个月每天的订单量怎么样?周末和工作日差别大吗?"如果用 GROUP BY created_at 直接按天分组,输出的是一串日期,很难直接看出规律。用 CASE WHEN 先把日期归到"工作日"或"周末",再聚合,分析效率会高不少:

SELECT CASE WHEN DAYOFWEEK(created_at) IN (1, 7) THEN '周末' ELSE '工作日' END AS day_type, COUNT(*) AS order_cnt, ROUND(SUM(order_amount) / COUNT(*), 2) AS avg_amount FROM orders WHERE created_at >= '2024-01-01' GROUP BY day_type;

MySQL 的DAYOFWEEK()返回 1 表示周日,7 表示周六,这是很容易记混的一个函数。这个查询把"按条件分组"的逻辑放在了 CASE WHEN 里,GROUP BY 直接引用 SELECT 里的别名,语法上 MySQL 允许这样用,在标准 SQL 里也支持按表达式分组。

如果是做周维度统计,同样可以用WEEK(created_at)配合 CASE WHEN 来重新编号。我实际做过一个数据补录系统,要把漏采的数据按"是否补录"分两类统计,核心条件就是CASE WHEN recorded_at > created_at THEN '补录' ELSE '正常' END,一条 SQL 就把两类占比算得明明白白。

3.2 UPDATE 语句中的条件更新:避免多条 SQL

CASE WHEN 不只是 SELECT 的专利,UPDATE 语句里配合使用,可以避免写多条 UPDATE 导致的中间状态问题。比如某个商品表要做阶梯调价,采购价超过 100 的涨 5%,50 到 100 之间的涨 3%,50 以下保持不变,用一条语句解决:

UPDATE products SET price = CASE WHEN purchase_price > 100 THEN ROUND(purchase_price * 1.05, 2) WHEN purchase_price >= 50 THEN ROUND(purchase_price * 1.03, 2) ELSE price END WHERE active = 1;

这里要注意 CASE WHEN 在 UPDATE 中的作用是逐行计算新值,WHERE 条件负责筛选参与更新的行。如果某个分支的 THEN 结果是原来的字段本身(比如上面的 ELSE price),效果就是该行保持不变,避免无谓的写操作。

更复杂一点的场景是"同一张表内不同分组更新到不同列"。比如会员表要根据积分来刷新等级和折扣,两个字段的更新逻辑其实是同一套条件判断。虽然 MySQL 不允许在 SET 子句里复用另一个字段的 CASE 别名,但你可以把两个字段分别写成相同的 CASE 条件,SQL 优化器会智能地只计算一次表达式,所以性能不会翻倍。以前我用存储过程写这种循环更新,后来发现这种"同一条件批量更新多个字段"用 CASE WHEN 完全能搞定,代码还更简洁。

3.3 ORDER BY 里的自定义排序

这个用法很多人会忽略,但在成熟项目里极其实用。正常情况下 ORDER BY 只能按字段大小排序,可业务系统的状态流转顺序往往是自定义的。比如工单状态"待受理"→"处理中"→"已解决"→"已关闭",每个状态在数据库里可能存的是英文枚举或数字,想按业务流转顺序而不是字典序排序,就可以这么写:

SELECT ticket_id, status, created_at FROM support_tickets ORDER BY CASE status WHEN 'pending' THEN 1 WHEN 'processing' THEN 2 WHEN 'resolved' THEN 3 WHEN 'closed' THEN 4 ELSE 99 END, created_at DESC;

这个技巧在报表里也很有用。比如你要在 Excel 里导出一个省份列表,希望优先显示业务重点区域,再按拼音排其他省份,传统做法是加一个"排序优先级"字段,但用 CASE WHEN 完全可以免除额外的维护成本:

ORDER BY CASE province WHEN '广东' THEN 1 WHEN '上海' THEN 2 WHEN '北京' THEN 3 ELSE 10 END, province ASC;

这样查出来的结果就是"重点省份靠前,其余省份按拼音排"。注意 ELSE 10 这里不能省略,否则不是重点省份的行会被排到最前面(NULL 在升序时排最前),这个坑我亲测踩过。

4. 实战中容易踩的坑与调优经验

4.1 CASE WHEN 与 JOIN 联合使用时的性能陷阱

有些同学写多表关联的复杂查询时,习惯在 JOIN 的 ON 条件里放 CASE WHEN。我不建议这么做,原因有两个:第一,ON 条件里放 CASE WHEN 会严重影响优化器对连接顺序的判断,尤其是在多表连接时,可能导致执行计划选择错误的驱动表;第二,ON 条件的 CASE WHEN 如果是非等值判断,可能让数据库放弃使用索引,退化成全表扫描。

比如这种写法是完全可以避免的:

-- 不推荐:ON 子句里带 CASE WHEN SELECT * FROM orders o LEFT JOIN users u ON o.user_id = u.id AND CASE WHEN o.channel = 'app' THEN u.is_app_user = 1 ELSE 1 END;

更好的做法是:在 JOIN 里只保留关联条件,把 CASE WHEN 的判断放到 WHERE 或 SELECT 里。如果确实需要在关联时过滤,也应当先缩小子集再 JOIN:

SELECT * FROM orders o LEFT JOIN ( SELECT id, name, is_app_user FROM users WHERE is_app_user = 1 OR o.channel <> 'app' -- 注意:这里其实还是有问题,最好在子查询里先算好,或者拆开来处理 ) u ON o.user_id = u.id;

遇到这种复杂逻辑,我会建议先拆解成多个简单查询再合并,或者用临时表/派生表把"判断逻辑"提前物化。SQL 优化器虽然智能,但它看不懂业务规则,让条件判断放在它擅长优化的地方,性能才会稳。

4.2 类型转换与 NULL 的隐性坑

CASE WHEN 的各分支返回值类型需要保持一致,否则 MySQL 会做隐式类型转换。最常见的问题是 THEN 分支返回字符串,某天有同事在代码里加了 ELSE 0,结果所有行长这样'已发货0'、'待支付0'——因为 CASE 表达式返回的是字符串类型,数字 0 被自动转成了 '0' 拼接到字符串后面了。反过来,如果数值分支和字符串分支混合,会出现数值优先的情况,字符串被转成 0,导致显示结果变成 0.0 之类的怪值。

另一个比较隐蔽的是判断 NULL。千万别写:

CASE WHEN column_name = NULL THEN '空' ELSE '非空' END

这永远会返回"非空",因为 NULL 不能通过=比较,必须用IS NULL或<=>(NULL 安全等于操作符)。正确的写法是:

CASE WHEN column_name IS NULL THEN '空' ELSE '非空' END

NULL 参与 CASE 判断时还有一个细节:如果 THEN 结果里有 NULL,这本身没问题,但如果这个 CASE 表达式被用于 JOIN 关联或 WHERE 条件,NULL 比较会产生逻辑矛盾。所以在写"根据字段是否为空决定映射"的时候,我习惯把 IS NULL 判断放在所有其他条件之前,避免先命中其他分支。

4.3 大数据量下的索引利用与优化策略

CASE WHEN 本身不会导致索引失效——它只是个表达式,真正决定能不能走索引的是 WHERE 条件和分组字段。但如果你的 CASE WHEN 写在 WHERE 子句里,比如:

SELECT * FROM orders WHERE CASE WHEN order_status = 2 THEN order_status = 2 ELSE user_id = 100 END;

这种写法会让优化器彻底懵掉,因为它无法将这个表达式拆解为等值条件,索引就不可能用上。我排查过好几次线上慢查询,最终定位都是这种"在 WHERE 里写逻辑判断"的写法。解决办法永远是"把 CASE WHEN 从 WHERE 里抽出来"——如果条件是对某个字段的等值判断,直接写WHERE order_status = 2 OR user_id = 100;如果是业务规则复杂,考虑拆分 UNION。

对于 GROUP BY 和聚合函数里套的 CASE WHEN,只要底层物理表够大,建议先建好针对"分组字段 + 过滤字段"的复合索引。比如前面那个按"日期类型(工作日/周末)"分组的例子,如果查询频繁,可以在 created_at 上建索引,让 WHERE 先按日期范围过滤,再到内存里做 CASE 分组。聚合本身如果只需要部分列,也尽量减少 SELECT 的字段数量,降低临时表的内存压力。

4.4 可读性维护:代码 Review 中 CASE WHEN 的规范

写 SQL 和写代码一样,难的不是跑通,而是半年后别人(甚至你自己)还能看懂。我参与过的项目里,凡是 CASE WHEN 写成一坨超过 20 行、没有缩进、没有注释的,Review 时基本都会被要求重写。这里有几个我总结的维护心得:

  • 每个 WHEN 一行,THEN 的结果清晰对应一个缩进层级,END 单独一行。
  • 分支有条件顺序逻辑(比如区间判断),在开头用注释标明"注意顺序不可调整"。
  • 在 UPDATE 中 CASE WHEN 更新多个字段时,尽量让两个字段的 CASE 结构对齐,避免后续维护时只改了一个字段的规则。
  • 给 CASE 表达式起一个有业务含义的别名,比如 status_label、growth_bucket,别叫 temp、result。

其实 CASE WHEN 的书写风格和代码一样,每个团队可以有自己的规范,但"结构化、对齐、注释"这三条是通用的。SQL 写得好不好看,在关键时刻是能反映工程素养的。

5. 从简单映射到复杂业务逻辑的进阶示例

5.1 分箱(Binning)分析:把连续变量转为分类变量

数据分析里经常要把年龄、价格、时长这类的连续字段分成几个区间。CASE WHEN 是天然的分箱工具。比如用户年龄分布统计:

SELECT CASE WHEN age < 18 THEN '未成年人' WHEN age < 30 THEN '18-29岁' WHEN age < 45 THEN '30-44岁' WHEN age < 60 THEN '45-59岁' ELSE '60岁以上' END AS age_group, COUNT(*) AS user_cnt FROM users WHERE active = 1 GROUP BY age_group ORDER BY user_cnt DESC;

注意我在这里严格按从大到小/从小到大的区间顺序写条件,因为每个年龄只应归入一个分箱,前面提到的"从上到下命中即返回"特性在分箱场景下反而是好帮手。加上 ALTER TABLE 或视图定义后,这种逻辑还能复用成公共 SQL,避免到处复制粘贴。

5.2 嵌套 CASE WHEN 处理多层级业务规则

有些业务判断是分层的,比如风控系统里判断一笔交易是否需要人工审核。如果只用一个 CASE WHEN 把条件全部铺开,会很乱;更好的做法是外层 CASE 先判断大类,内层 CASE 再细化子条件。比如:

SELECT transaction_id, CASE WHEN amount > 5000 THEN CASE WHEN risk_score >= 80 THEN '高优审核' WHEN risk_score >= 60 THEN '标准审核' ELSE '抽查' END WHEN amount > 1000 THEN CASE WHEN risk_score >= 70 THEN '标准审核' ELSE '自动通过' END ELSE '自动通过' END AS review_level FROM transactions;

这个例子体现了嵌套 CASE WHEN 的层级化解法:外层按金额划分大的等级,内层按风险分做二次细化。不要试图把所有条件拍扁成一个 CASE,那样分支数量会爆炸。维护这种嵌套查询时,配合注释缩进对齐,逻辑非常清晰。

5.3 与窗口函数一起用:CASE WHEN + ROW_NUMBER/RANK

CASE WHEN 和窗口函数组合很强大,比如"每个用户最近一笔有效订单是什么"。先用 ROW_NUMBER 给每个用户按时间倒排序,再用 CASE WHEN 把排名为1的记录标记出来:

WITH ranked_orders AS ( SELECT order_id, user_id, order_amount, created_at, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn FROM orders WHERE order_status <> 4 -- 排除已取消 ) SELECT user_id, order_id, order_amount FROM ranked_orders WHERE rn = 1;

这里没直接用到 CASE WHEN,但如果想同时输出"最近一笔有效订单金额"和"该用户累计订单数",可以用聚合+条件逻辑组合:

WITH order_stats AS ( SELECT user_id, COUNT(*) AS total_cnt, SUM(CASE WHEN order_status <> 4 THEN order_amount ELSE 0 END) AS valid_total_amt FROM orders GROUP BY user_id ) SELECT u.id, u.name, s.total_cnt, s.valid_total_amt FROM users u LEFT JOIN order_stats s ON u.id = s.user_id;

窗口函数解决"每 Top N"问题,CASE WHEN 解决"按条件加权聚合"问题,两者组合后几乎能覆盖 90% 的复杂分析需求。而且这类查询在 EXPLAIN 里通常走"Using index"或"Using temporary",性能表现远好于用子查询做关联聚合的写法。

6. 工作中关于 CASE WHEN 的三条总结性建议

第一,能不用 OR 条件拼接复杂逻辑时,优先考虑用 CASE WHEN 拆分。多个 OR 条件会让优化器难做索引选择,而 CASE WHEN 配合聚合函数能把复杂逻辑变成一行行清晰的打分规则。第二,写 CASE WHEN 时永远把最具体的条件放最前面,并且不要省略 ELSE。如果分支太多(超过七八个),就要回头审视是不是业务设计有问题,或者应该拆表拆查询。第三,善用 EXPLAIN 观察 CASE WHEN 所在的查询计划——一个好的 CASE WHEN 写法应该是"过滤条件下推、聚合在内存完成、排序走索引",如果看到 Using filesort 和 Using temporary 同时出现,就该优化了。

记得我刚开始接触 CASE WHEN 时,总觉得这是编程语言里 if-else 的直接翻译,没什么稀罕。直到有次做一个多维度销售报表,十几个统计口径的不同条件组合,我用了一长串 UNION ALL 拼出几百行 SQL,被团队同事改成三个带 CASE WHEN 的聚合查询搞定后,我才真正意识到:SQL 不只是"取数工具",它本身就是一种表达业务逻辑的语言。CASE WHEN 就是这门语言里表达判断分支最重要的关键字。掌握它之后,你的 SQL 表达力会上一个大台阶。

最后分享一个我在实际项目中常用的调试小技巧:写复杂的 CASE WHEN 之前,先在 SELECT 里用原始字段做一版不带聚合的查询,把每一行的 CASE 命中结果打出来肉眼检查一遍,确认无误后再包上 GROUP BY 或聚合函数。这样可以快速定位是"条件写错"还是"聚合逻辑算错",比直接跑一个几百行的最终 SQL 然后查结果快得多。

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

MMORPG服务端架构实战:从冒险岛源码学权威校验与状态同步

简介&#xff1a;本资源为《冒险岛》经典2D横版网游的服务器端源代码解析资料&#xff0c;面向游戏服务端开发初学者、Java/C后端工程师及网络游戏架构学习者&#xff0c;聚焦高并发网络通信、游戏逻辑分层设计与分布式服务基础实践。压缩包为RAR格式&#xff0c;大小6.42MB&am…

作者头像 李华
网站建设 2026/10/13 4:28:04

CKEditor Word格式组件选型:车企复杂文档导入与还原实战

很多车企信息化项目里都有一个反复出现的尴尬场景&#xff1a;技术部门用Word写好了SOP、维修手册、检测报告&#xff0c;要传到OA或者知识管理系统的网页编辑框里&#xff0c;结果粘贴过去以后多级标题全部变成了普通段落&#xff0c;表格错位得像一张乱拼的Excel&#xff0c;…

作者头像 李华
网站建设 2026/10/13 4:27:38

微电网两台DG主从控制孤岛并网平滑切换仿真分析

做微电网仿真这两年&#xff0c;绕不开的一个课题就是“模式切换”。尤其是那种两台DG组成的小型微电网&#xff0c;既要能在并网状态跑PQ给主网送功率&#xff0c;又要在孤岛状态下维护母线电压和频率&#xff0c;还要在两种模式之间来回切得平滑、不炸机&#xff0c;确实要点…

作者头像 李华
网站建设 2026/10/13 4:27:22

YOLOv11火灾烟雾数据集训练实战:3600张标注图从划分到部署

简介&#xff1a;面向火灾烟雾检测与YOLO目标检测实践者&#xff0c;这份已标注数据集包含3600张真实场景图片&#xff0c;覆盖不同光照条件、烟雾密度、火灾阶段与监控视角&#xff0c;可支撑目标检测模型的训练、验证和调优。压缩包共2000个文件&#xff0c;其中1996个XML文件…

作者头像 李华
网站建设 2026/10/13 4:26:47

舌苔数据集实战:从labelme标注到PyTorch语义分割全流程

简介&#xff1a;面向中医舌诊研究与深度学习应用的舌苔图像数据集&#xff0c;收录两千余张512512像素的原图&#xff0c;并配有Labelme标注的JSON标签&#xff0c;覆盖黑苔、地图舌、白厚腻苔、紫苔、红厚腻苔、红舌黄腻苔等常见舌象类型&#xff0c;适用于图像分类、目标检测…

作者头像 李华
网站建设 2026/10/13 4:26:03

Linux内核链表实战:从自然数重排掌握list_head核心操作

1. 从一道内核链表题说起&#xff1a;为什么值得认真拆解第一次看到“用链表存储若干自然数&#xff0c;把 1 2 3 4 5 6 7 8 9 重排成 1 3 5 7 9 8 6 4 2”这个题目时&#xff0c;很多人第一反应是“这不就是个数组排序题吗&#xff0c;开个数组分奇偶两半&#xff0c;奇数正着…

作者头像 李华