Laravel+PostgreSQL报double precision > interval运算符不存在错误
问题原因
报错本质是SQL语句中比较运算符两侧的数据类型不匹配:
>左侧的毛利率计算逻辑(COALESCE(((NULLIF((project_members.hourly_rate - last_known_user_costs.cost), 0)/NULLIF(project_members.hourly_rate, 0)) * 100),0)返回的是双精度浮点数(double precision)类型>右侧的子查询错误地将配置值强转为INTERVAL(时间间隔)类型,PostgreSQL没有定义浮点数和时间间隔的大小比较规则,因此直接抛出运算符不存在的错误。
毛利率阈值是百分比数值,完全不需要转成时间间隔类型,::INTERVAL属于错误的类型转换写法。
修复步骤
- 修正子查询的类型转换逻辑,将配置值转为数值类型,和左侧计算结果类型对齐
修正后的LaravelselectRaw代码如下:selectRaw('(CASE WHEN (COALESCE(((NULLIF((project_members.hourly_rate - last_known_user_costs.cost), 0)/NULLIF(project_members.hourly_rate, 0)) * 100),0) > ( SELECT value::NUMERIC FROM "configuration" WHERE "key" = \'Gross Margin Per Resource Yellow\' )) THEN \'red\' WHEN (COALESCE(((NULLIF((project_members.hourly_rate - last_known_user_costs.cost), 0)/NULLIF(project_members.hourly_rate, 0)) * 100),0) > ( SELECT value::NUMERIC FROM "configuration" WHERE "key" = \'Gross Margin Per Resource Green\' )) THEN \'green\' ELSE \'red\' END) AS status') - 校验配置值格式
确认configuration表中两个毛利率阈值的存储格式为纯数字,如果存的是带%后缀的字符串,需要先去除符号再转类型,将子查询中的value::NUMERIC替换为trim(value, '%')::NUMERIC即可。 - 校验业务判断逻辑
当前CASE语句的判断顺序存在逻辑风险:如果Green阈值大于Yellow阈值(符合常规业务规则:毛利率越高状态越好),那么所有大于Yellow阈值的结果都会在第一个WHEN分支命中返回red,永远不会走到Green状态的判断。
常规毛利率状态判断逻辑应该先匹配更高的阈值,参考写法:
可根据实际业务规则调整分支顺序和返回值。CASE WHEN 毛利率计算值 > (SELECT value::NUMERIC FROM configuration WHERE key = 'Gross Margin Per Resource Green') THEN 'green' WHEN 毛利率计算值 > (SELECT value::NUMERIC FROM configuration WHERE key = 'Gross Margin Per Resource Yellow') THEN 'yellow' ELSE 'red' END
内容的提问来源于stack exchange,提问作者Jarliev Pérez
相关产品推荐
相关产品推荐

