Rails现有ActiveRecord查询添加除法计算及PG语法错误排查
问题解决方法
报错原因
- 直接语法问题:你的SELECT语句中
(total_shares_number/#{divisor}缺少右括号,导致SQL解析时遇到FROM关键字触发语法错误 - 隐藏逻辑问题:SQL规范不允许在同个SELECT子句中引用刚定义的别名
total_shares_number,即使补上括号也会报字段不存在的错误
正确实现代码
修改后的PortfolioShareholdersQuery类如下:
class PortfolioShareholdersQuery def initialize(portfolio) @portfolio = portfolio end def call # 提前获取除数,增加空值、零值校验避免运行错误 divisor = portfolio.portfolio_setup_infos.last&.total_shares_sold raise ArgumentError, "对应投资组合未配置总发售份额" if divisor.blank? || divisor.zero? User.joins(:cash_transactions) .where(cash_transactions: { to_wallet: portfolio.wallet }) .select(<<~SQL.squish) users.*, SUM(cash_transactions.shares_number) as total_shares_number, ROUND(SUM(cash_transactions.shares_number)::numeric / #{divisor}::numeric, 4) as share_holding_ratio SQL .group('users.id') end attr_reader :portfolio end
实现说明
- 重复使用
SUM(cash_transactions.shares_number)替代别名引用,符合SQL执行逻辑 - 增加
::numeric类型转换,避免PostgreSQL默认整数除法导致结果取整丢失精度 - 用
ROUND函数控制返回的小数位数,可根据业务需求调整保留位数 - 查询返回的User对象可直接读取
total_shares_number和share_holding_ratio两个动态属性
内容的提问来源于stack exchange,提问作者mr_muscle
相关产品推荐
相关产品推荐

