MySQL CTAS搭配CASE转数值时出现DOUBLE截断警告如何解决
警告触发原因
警告的核心触发点是同列返回值类型不统一触发隐式类型转换:
- 你在
CASE语句中对NewOutValue、OldOutValue做+0.0运算后按数值比较,MySQL会默认把test2列识别为数值类型 - 但比较不满足时你返回了空字符串
'',MySQL需要把空字符串转成DOUBLE类型和同列其他值类型对齐,空字符串转数值过程中就会抛出Truncated incorrect DOUBLE value: ''警告 - 另外原SQL的WHERE子句中重复写了两次
wca.bochg.BochgID is null,属于冗余逻辑,不影响结果但可以删除 - 用
+0.0做隐式数值转换的写法可控性差,不同SQL模式下可能出现不同的转换结果,也是隐性问题
修复方法
按两个原则调整即可彻底消除警告:
- 统一同列返回值类型,数值列不要返回字符串类型值:条件不满足时如果需要占位,用
NULL或者符合业务要求的默认数值(比如0),不要用空字符串 - 用显式
CAST转换代替+0.0的隐式转换,转换的数值精度(比如DECIMAL(18,4))可以根据业务实际存储的数值长度调整,避免隐式转DOUBLE带来的精度问题和不可控的转换警告
修复后的完整SQL如下:
CREATE TABLE wm.bochg AS SELECT wca.bochg.BochgID, wca.bochg.SecID, wca.bochg.OldOutValue, wca.bochg.NewOutValue, CASE WHEN CAST(NewOutValue AS DECIMAL(18,4)) >= CAST(OldOutValue AS DECIMAL(18,4)) THEN CAST(NewOutValue AS DECIMAL(18,4)) ELSE NULL END AS test2 FROM wca.bochg WHERE wca.bochg.SecID IN (SELECT secid FROM client.pfisin WHERE accid = 416) AND ( wca.bochg.BochgID IS NULL OR wca.bochg.BochgID = ( SELECT subbochg.BochgID FROM wca.bochg AS subbochg WHERE subbochg.secid = wca.bochg.secid AND subbochg.Actflag <> 'D' AND CAST(subbochg.NewOutValue AS DECIMAL(18,4)) >= CAST(subbochg.OldOutValue AS DECIMAL(18,4)) ORDER BY subbochg.BochgID DESC LIMIT 1 ) );
补充:如果业务要求不满足条件时test2列必须显示为空字符串,那就不能把test2列建成数值类型,需要先把所有返回值统一成字符串类型:把THEN后面的数值用
CAST(NewOutValue AS CHAR)转成字符串再返回,不过这种写法会让test2列失去数值属性,后续做数值计算还需要再转换,不推荐使用。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

