递归SQL查询斜率与截距结果异常:需转换为FLOAT类型
解决递归SQL中斜率和截距的类型问题
我一眼就看出问题出在哪了——你的锚点查询里用了整数字面量1和0来初始化slope和intercept,这会让SQL引擎默认把这两个字段识别为整数类型。而递归CTE的字段类型是由锚点查询定义的,所以后面整个递归过程中,哪怕你做了浮点运算,结果都会被强制截断成整数,自然得不到正确的斜率和截距值。
要解决这个问题很简单,只需要在锚点查询里把这两个字段显式转换成FLOAT类型就行,有两种常用方式:
方式1:使用CAST函数显式转换
修改后的递归CTE锚点部分:
WITH RECURSIVE t AS ( SELECT id parentId, idPublic parentIdPublic, name parentName, slope parentSlope, intercept parentIntercept, id, idPublic, name, type, CAST(1 AS FLOAT) slope, -- 显式转成FLOAT类型 CAST(0 AS FLOAT) intercept, -- 显式转成FLOAT类型 value FROM measurements WHERE id IN (414,415,416,417,491) UNION ALL SELECT t.parentId, t.parentIdPublic, t.parentName, t.parentSlope, t.parentIntercept, ... )
方式2:直接使用浮点字面量
如果你用的SQL支持(大部分主流数据库都支持),也可以直接用带小数点的字面量来初始化,这样引擎会自动识别为浮点类型:
WITH RECURSIVE t AS ( SELECT id parentId, idPublic parentIdPublic, name parentName, slope parentSlope, intercept parentIntercept, id, idPublic, name, type, 1.0 slope, -- 用浮点字面量初始化 0.0 intercept, -- 用浮点字面量初始化 value FROM measurements WHERE id IN (414,415,416,417,491) UNION ALL SELECT t.parentId, t.parentIdPublic, t.parentName, t.parentSlope, t.parentIntercept, ... )
这样修改后,slope和intercept字段在整个递归过程中都会保持FLOAT类型,后续的计算就能保留正确的浮点精度,返回符合预期的结果了。
内容的提问来源于stack exchange,提问作者user1032531
相关产品推荐
相关产品推荐

