MySQL中使用CASE语句计算折扣后价格异常,请求排查问题
问题分析与修正
原查询的核心问题:
CASE语句语法错误
你写的CASE price WHEN td.agent_id = 2 THEN ...是CASE的简单格式,逻辑是判断price是否等于td.agent_id = 2的结果(MySQL中布尔值以0/1存储),这和你要判断agent_id是否为2的逻辑完全不符,导致永远走ELSE分支,total始终等于原价。JOIN条件未关联agent_id
training_discounts的折扣是绑定到特定agent和schedule的,原LEFT JOIN只关联了ts.id = td.schedule_id,没有关联ts.agent_id = td.agent_id,会导致匹配到其他agent的折扣数据,或者无法正确匹配到对应agent的折扣。GROUP BY子句不合理
SELECT中的ts.id、name等字段都不在GROUP BY中,且LEFT JOIN后td.schedule_id可能为NULL(无折扣的schedule),会导致数据被错误合并,丢失明细。
修正后的SQL语句
如果每个training_schedules对应唯一的agent折扣(即一个schedule+agent组合只有一条折扣记录),可以用以下语句:
SELECT ts.id, ts.name, ts.training_types, DATE_FORMAT(ts.date_start ,'%d/%m/%Y') as date_start, DATE_FORMAT(ts.date_end ,'%d/%m/%Y') as date_end, ts.quota, ts.price, td.discount, -- 使用搜索式CASE,直接判断agent_id条件 CASE WHEN td.agent_id = 2 THEN (ts.price - td.discount) ELSE ts.price END as total FROM training_schedules ts LEFT JOIN training_discounts td ON ts.id = td.schedule_id AND ts.agent_id = td.agent_id; -- 关联agent_id,确保匹配对应agent的折扣
如果一个schedule可能对应多个折扣(比如不同agent的折扣),且你只需要agent_id=2的折扣,也可以调整JOIN条件,只匹配目标agent的折扣:
SELECT ts.id, ts.name, ts.training_types, DATE_FORMAT(ts.date_start ,'%d/%m/%Y') as date_start, DATE_FORMAT(ts.date_end ,'%d/%m/%Y') as date_end, ts.quota, ts.price, td.discount, -- 因为已经JOIN了agent_id=2的折扣,直接判断discount是否存在即可 CASE WHEN td.discount IS NOT NULL THEN (ts.price - td.discount) ELSE ts.price END as total FROM training_schedules ts LEFT JOIN training_discounts td ON ts.id = td.schedule_id AND td.agent_id = 2; -- 只匹配agent_id=2的折扣记录
内容的提问来源于stack exchange,提问作者Ying
相关产品推荐
相关产品推荐

