Двойное соединение на одном столе дает неверный результат - PullRequest
0 голосов
/ 23 декабря 2018

В основном у меня есть 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 голосов
/ 28 декабря 2018

Вы присоединяетесь к одной и той же таблице дважды, и это умножит количество полученных строк, поэтому вы получите кратные ожидаемого результата.Просто присоединитесь к нему один раз и отфильтруйте в избранном, как это:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...