ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

mysql数据库常用数值函数、流程函数与 CASE WHEN

mysql数据库常用数值函数、流程函数与 CASE WHEN CASE WHEN 行转列为什么总要套一层 MAX我曾把CASE WHEN subjectMath THEN score END直接写进GROUP BY查询结果不是数据库报错就是每个学生只取到了“第一行”那门课的成绩。这篇把数值函数、条件分支和行转列串成一条问题链读完你能独立写出跨库通用的透视查询并避开取整、空值、聚合三处暗坑。一、一张成绩长表要折叠成宽表你拿到一张学生成绩表student_scores同一个学生的每门课各占一行。报表侧不想要这种“竖着长”的结构要的是“一人一行、一科一列”。原始长表namesubjectscoreAliceMath90AliceEnglish85BobMath92BobEnglish88目标宽表namemath_scoreenglish_scoreAlice9085Bob9288长表变宽表本质是两个动作把对应科目的值挑出来再把同一个人的多行压成一行。可在折叠之前单值层面的“算”和“判”得先打通——先从最容易算错的数值函数说起。二、数值函数同样取整为什么账面对不上我在财务模块里用FLOOR处理过金额本想“四舍五入到分”结果每笔都被向下抹掉零头对账时差了一截。取整函数写错不是语法问题是口径问题。取整四件套的边界差异函数动作示例结果ROUND(x,d)四舍五入到 d 位ROUND(3.6,0)4CEIL(x)向上取整CEIL(3.6)4FLOOR(x)向下取整FLOOR(3.6)3TRUNC(x,d)直接截断不舍入TRUNC(3.1415,3)3.141其余高频数值函数函数返回典型用途ABS(x)绝对值偏差大小ABS(预测-实际)SIGN(x)正1 / 负-1 / 零0偏差方向、自定义排序MOD(x,y)x 除以 y 的余数判奇偶、数据分片RAND()0~1 随机浮点数随机抽样、验证码POWER/SQRT/LN幂、平方根、对数复利、特征工程数值函数的共同特征是“数字进、数字出”识别业务里哪里需要对齐和规范化比背语法更重要。**记住**取整函数的本质是对齐口径——财务对分用 ROUND、年龄分桶用 FLOOR、总页数用 CEIL选错函数就是算错账。值算准了可业务要“不同分数给不同等级、空值给默认值”SQL 靠什么做分支三、流程函数与 CASE WHEN让 SQL 学会看情况空值NULL处理和条件分支是流程函数的主战场。三个常用函数的差异函数行为适用IF(cond,a,b)条件真取 a否则 b二选一MySQL 专有IFNULL(a,b)a 非空取 a否则 b单字段兜底COALESCE(a,b,…)取第一个非空值多字段依次兜底注意空字符串font stylecolor:#c00;/font在 IFNULL 眼里不算 NULL会被原样返回不会走兜底值。条件表达式CASE WHEN有两种形态。简单 CASE 做相等匹配CASEsubjectWHENMathTHEN理科WHENEnglishTHEN文科ELSE其他END搜索 CASE 做区间判断每个 WHEN 跟一个布尔条件CASEWHENmath85THEN优秀WHENmath60THEN及格ELSE不及格END两种形态的选择维度简单 CASE搜索 CASE判断方式与某值相等满足某条件适用状态码转文本区间、多条件、NULL类比值到标签映射if-elif-else我在等级映射里把WHEN math 60写在了WHEN math 85前面85 分以上的学生全部被压成了“及格”。CASE 一旦命中就短路后面的条件不再计算。**记住**CASE 命中即停条件顺序就是业务优先级区间判断务必从窄到宽、从严到宽排。单值会判了可开头每个学生有两行怎么把它们压成一行这就轮到行转列Pivot登场。四、行转列为什么 MAX 非套不可行转列的完整链路可以拆成三个动作长表两行/人 CASE WHEN 行级取值 GROUP BY 压缩 宽表一行/人 ------------- -------------------- -------------- ------------- Alice Math 90 - math90, engNULL --\ Alice Eng 85 - mathNULL,eng85 --- 按 name 分组 -- Alice 90 85 Bob Math 92 - math92, engNULL --- MAX 取值 -- Bob 92 88 Bob Eng 88 - mathNULL,eng85 --/跨库通用的写法是 CASE WHEN 配合聚合函数SELECTname,MAX(CASEWHENsubjectMathTHENscoreEND)ASmath_score,MAX(CASEWHENsubjectEnglishTHENscoreEND)ASenglish_scoreFROMstudent_scoresGROUPBYname;为什么非套 MAX 不可GROUP BY要求把同组多行压成一行CASE WHEN 只是行级地产生值数据库还需要知道“这些值怎么合并”。MAX 就是那个合并规则每组每科只有一个非空值时MAX 等价于“把那个值取出来”。聚合函数按数据形态选择函数适用形态MAX / MIN取唯一值、极端值一人一科一值最常用SUM数值累加AVG取平均COUNT统计满足条件的行数Oracle、SQL Server 提供原生 PIVOT逻辑等价、写法更短SELECT*FROM(SELECTname,subject,scoreFROMstudent_scores)PIVOT(MAX(score)FORsubjectIN(MathASmath_score,EnglishASenglish_score));跨库兼容一览数据库CASE WHEN 聚合原生 PIVOTMySQL / PostgreSQL支持不支持Oracle / SQL Server支持支持**记住**CASE WHEN 在行级挑出值聚合函数在组级压成行——这是 GROUP BY 语义下的硬要求不是可选项。拆明白了落到真实报表整套写法长什么样五、综合实战季度消费交叉报表订单表orders(user_id, order_date, amount)需求是按用户汇总 2026 年各月消费并对任意单月超过 10000 的用户标“高消费”。SELECTuser_id,SUM(CASEWHENMONTH(order_date)1THENamountELSE0END)ASjan_amount,SUM(CASEWHENMONTH(order_date)2THENamountELSE0END)ASfeb_amount,SUM(CASEWHENMONTH(order_date)3THENamountELSE0END)ASmar_amount,CASEWHENSUM(CASEWHENMONTH(order_date)1THENamountELSE0END)10000ORSUM(CASEWHENMONTH(order_date)2THENamountELSE0END)10000ORSUM(CASEWHENMONTH(order_date)3THENamountELSE0END)10000THEN高消费ELSE普通ENDASuser_levelFROMordersWHEREYEAR(order_date)2026GROUPBYuser_id;每一层各管一段层职责MONTH(order_date)提取月份供条件判断内层 CASE WHEN行级选择性取值SUM组级把各月金额累加外层 CASE基于聚合结果再判一次等级你可以用下面的最小数据自行验证CREATETABLEorders(user_idINT,order_dateDATE,amountDECIMAL(10,2));INSERTINTOordersVALUES(1,2026-01-08,6000.00),(1,2026-01-20,5000.00),(1,2026-02-11,2000.00),(2,2026-02-05,3000.00),(2,2026-03-12,4000.00);查询返回user_id jan_amount feb_amount mar_amount user_level 1 11000.00 2000.00 0.00 高消费 2 0.00 3000.00 4000.00 普通用户1 一月合计 11000 命中阈值正确标为高消费缺数据月份落到 0结果符合预期。**记住**行级取值、组级聚合、外层基于结果再判一次三层职责分开透视报表就不会乱。六、总结延伸数值函数决定“值怎么变”流程函数决定“在什么条件下变”行转列则把两者合到一起条件表达式做行级筛选聚合函数做组级压缩把分散的行折叠成结构化的列。最容易翻车的几个点场景省略 ELSE显式 ELSESUM不匹配贡献 NULL被忽略贡献 0不影响合计COUNTCOUNT(CASE WHEN... THEN 1 END)统计满足条件行数...THEN 1 ELSE 0 END统计全部行想要“无成绩”显式为 0在 ELSE 里写 0或外层用 COALESCE 兜底。透视列很多时先用子查询或 CTE 压缩数据再做透视。跨库代码优先用标准语法 COALESCE 与 CASE WHEN。术语速查表术语英文/写法含义空值NULL未知值不等同于空字符串或 0条件表达式CASE WHEN行级分支判断命中即短路行转列Pivot长表按某列取值展开为多列聚合函数MAX/SUM/AVG/COUNT组级把多行压缩成一个值取值靠 CASE、压缩靠聚合、分组靠 GROUP BY——记住这条主线再复杂的数据塑形也有下手处。参考链接MySQL 8.0 数学函数官方文档MySQL 8.0 流程控制函数官方文档MySQL 8.0 CASE 表达式官方文档MySQL 8.0 聚合函数官方文档Oracle PIVOT 官方文档
返回列表