在同一表上的两次联接产生错误的结果

时间:2018-12-23 13:20:14

标签: ruby-on-rails postgresql activerecord

基本上我有一个Driver模型,其中有许多rides。那些rides的字段为price,我想计算驾驶员的total_paid(他们一直以来的收入)和this_week_paid(该付款仅通过从本周开始到结束)在一个活动记录查询中。

通过这样的一个连接,我很容易达到了total_paid部分的正确数量:

Driver.joins(:rides).
  select("#{Driver.table_name}.*, sum(substring(rides.price from '[0-9]+.[0-9]*')::numeric) as total_paid").
  group("#{Driver.table_name}.id").
  order("total_paid DESC, id")

现在,当我尝试向该查询添加this_week_paid

Driver.joins("INNER JOIN rides this_week_rides ON #{Driver.table_name}.id = this_week_rides.driver_id").
  joins("INNER JOIN rides all_rides ON #{Driver.table_name}.id = all_rides.driver_id").
  select("#{Driver.table_name}.*, " +
             "sum(substring(this_week_rides.price from '[0-9]+.[0-9]*')::numeric) as this_week_paid, " +
             "sum(substring(all_rides.price from '[0-9]+.[0-9]*')::numeric) as total_paid").
  where(this_week_rides: { created_at: Time.current.beginning_of_week..Time.current.end_of_week }).
  group("#{Driver.table_name}.id").
  order("this_week_paid DESC, id")

它运行时不会引发任何异常,有趣的是,total_paid字段是正确数字的两倍,而this_week_paid字段是正确数字的三倍(查询答案:{ this_week_paid: 188.46, total_paid: 159.9 },正确答案:{ this_week_paid: 62.82, total_paid: 79.95 })。

我确实尝试添加where("this_week_rides.id != all_rides.id"),这给了我另一个错误的结果("this_week_paid" => 125.64,"total_paid" => 97.08

我想念什么?

1 个答案:

答案 0 :(得分:2)

您两次连接同一张表,这将使您获得的行数相乘,因此这就是为什么获得预期结果倍数的原因。只需加入一次,然后像这样过滤选择:

sum(substring(rides.price from '[0-9]+.[0-9]*')::numeric) filter (
  where rides.created_at between time1 and time2
) as this_week_paid,

sum(substring(rides.price from '[0-9]+.[0-9]*')::numeric) as total_paid