This is simplified data structures
schema "campaigns" do
belongs_to :created_by, User, type: :id
has_one :analytics
end
schema "analytics" do
belongs_to :campaign, Campaign
end
schema "message_records" do
belongs_to :campaign, Campaign
end
Campaign has_one analytics
. But more than one message_records
are belongs_to
one campaign.
Because campaign will have many(like 10-1000) meesages which has one message_records
each.
What I want is that return this value grouped_by campaign.created_by_id
user_id: campaign.created_by_id
total_campaigns_count: count(campaign.id),
total_messages_count: sum(a.sent_messages),
total_credit_used: sum(mdr.segments),
I tried
campaign_with_mdr =
base_query()
|> where([c], ^filters_with(filters))
|> join(:inner, [c], mdr in MessageDetailsRecord, on: c.id == mdr.campaign_id)
|> distinct(:id)
query =
from cm in subquery(campaign_with_mdr),
left_join: a in assoc(cm, :analytics),
group_by: [c.created_by_id],
select: %{
user_id: cm.created_by_id,
total_campaigns_count: count(c.id),
total_messages_count: sum(a.sent_messages),
total_credit_used: sum(mdr.segments)
}
Repo.all(query)
This query won’t return duplicate campaigns but can’t get a total_credit_used: sum(mdr.segments)
Then I tried other method
query =
from c in Campaign,
where: ^filters_with(filters),
left_join: a in assoc(c, :analytics),
join: mdr in MessageDetailsRecord,
on: c.id == mdr.campaign_id,
distinct: c.id,
group_by: [c.created_by_id, c.id],
select: %{
user_id: c.created_by_id,
total_campaigns_count: count(c.id),
total_messages_count: sum(a.sent_messages),
total_credit_used: sum(mdr.segments),
}
Repo.all(query)
This method’s problem is that I need to include c.id
into group_by
clause or not get an error says
ERROR 42803 (grouping_error) column "c0.id" must appear in the GROUP BY clause or be used in an aggregate function
Can you help?