#ruby-on-rails #postgresql #inner-join
#ruby-на-рельсах #postgresql #внутреннее соединение #ruby-on-rails
Вопрос:
Такого рода вопросы встречаются повсеместно… но вот в чем моя проблема.
У меня есть модели rails: Organization
, Activity
, Donation
, DonationItem
. Я пытаюсь получить суммирование Activity.hours
и DonationItem.amount
для каждого Organization
.
Я не могу использовать прямые отношения (например: Organization.activities.pluck(:hours).sum
потому что я нахожусь в ситуации, когда Organization.select("...").group(...)
необходимо использовать.
Текущие соединения rails приведены ниже, хотя на данном этапе они явно некорректны:
@relation = Organization.joins(:activities, donations: :donation_items)
.select("organizations.id, sum(activities.hours), sum(donation_items.amount)")
.group("organizations.id")
Это структура SQL (в основном …) select находится здесь: http://sqlfiddle.com /#!17/fb932e/6
Вот выбор для пользователей, которые не хотят просматривать SQL Fiddle
select
o.id,
sum(a.hours) as "hours",
sum(di.amount) as "amount"
from organizations o
inner join activities a
on a.organization_id = o.id
inner join donations d
on d.organization_id = o.id
inner join donation_items di
on di.donation_id = d.id
group by o.id
;
Я понимаю, в чем проблема, просто не нахожу решения для ее решения…
Будем признательны за любую помощь. Спасибо.
Ответ №1:
В SQL вы можете использовать CTE
подпункт or для устранения проблемы с неправильными значениями часов и количества, но не уверен, как бы вы преобразовали их в rails query Builder
Использование CTE
with organization_activity as (
select organization_id, sum(hours) as "hours"
from activities
group by organization_id
)
select
o.id,
a.hours as "hours",
sum(di.amount) as "amount"
from organizations o
inner join organization_activity a
on a.organization_id = o.id
inner join donations d
on d.organization_id = o.id
inner join donation_items di
on di.donation_id = d.id
group by o.id, a.hours
;
Используя подпункт
select
o.id,
a.hours as "hours",
sum(di.amount) as "amount"
from organizations o
inner join (
select organization_id, sum(hours) as "hours"
from activities
group by organization_id
) a
on a.organization_id = o.id
inner join donations d
on d.organization_id = o.id
inner join donation_items di
on di.donation_id = d.id
group by o.id, a.hours
;