MySQL按组列值除法实现?及长表转宽表简化方案
MySQL分组除法与长表转宽表的简便实现
一、按分组对列值进行除法运算
根据不同的业务场景,有两种常见的实现方式:
场景1:同一分组内指定类型数值相除
比如计算每个id下type=A的num除以type=B的num,可以结合条件聚合直接完成计算,同时处理除数为NULL或0的异常情况:
SELECT id, MAX(CASE WHEN type = 'A' THEN num END) AS num_A, MAX(CASE WHEN type = 'B' THEN num END) AS num_B, CASE WHEN MAX(CASE WHEN type = 'B' THEN num END) IS NOT NULL AND MAX(CASE WHEN type = 'B' THEN num END) != 0 THEN MAX(CASE WHEN type = 'A' THEN num END) / MAX(CASE WHEN type = 'B' THEN num END) ELSE NULL END AS ratio FROM your_table GROUP BY id;
场景2:分组内连续行数值相除
如果需要计算分组内当前行数值除以上一行数值,可以用窗口函数LAG()实现:
SELECT id, type, num, CASE WHEN LAG(num) OVER (PARTITION BY id ORDER BY type) IS NOT NULL AND LAG(num) OVER (PARTITION BY id ORDER BY type) != 0 THEN num / LAG(num) OVER (PARTITION BY id ORDER BY type) ELSE NULL END AS division_result FROM your_table;
二、长表转宽表的简便方法
你提到的JOIN/UNION方式确实繁琐,MySQL中最简洁高效的实现是条件聚合(CASE WHEN配合GROUP BY),无需多表关联:
实现代码
假设你的表名为your_table,执行以下SQL即可得到目标宽表:
SELECT id, MAX(CASE WHEN type = 'A' THEN num END) AS num_A, MAX(CASE WHEN type = 'B' THEN num END) AS num_B FROM your_table GROUP BY id;
逻辑说明
CASE WHEN会根据type匹配对应num,不匹配的行返回NULLMAX()聚合函数用于在同一id分组下提取对应type的唯一num值(因每个id+type唯一,用MIN/SUM也可,MAX是最常用的写法)- 无对应
type的id会显示NULL,与你需要的输出格式一致
内容的提问来源于stack exchange,提问作者Dang
相关产品推荐
相关产品推荐

