I am trying to build a basic report structure, and I have an id in table1, that is basically a user_id, that then any time a user does something or is associated with something, that ID is in other tables capturing those actions.
I would like to get for all the table1 records for a day, how records in these other tables are associated with these. (example for this user, he has 10 widgets, 15 sign_ins, 20 generic_actions)
Here's my query that gives the correct result, but SUPER inefficient returns about 6 million rows (when not distinct) and should only be a few thousand.
Results I'm getting says basically if I do this for one user and get the results above I get 1*10*15*20 rows returned, when I really want 1 row, with how many of each. Yes I know I can count distinct, but its still not joining right and searching so many rows that its prohibitive. Is there a join type or something I am missing to efficiently join without all the extra rows?
SELECT
DISTINCT DATE_TRUNC('day',table1.created_at) as c_date,
count(distinct table1.id) as t1_tot,
count(distinct table2.id) as t2_tot,
count(distinct table3.id) as t3_tot,
count(distinct table4.id) as t4_tot,
count(distinct table5.id) as t5_tot,
FROM
table1
LEFT JOIN
table2 ON table1.id = table2.t1_id
LEFT JOIN
table3 ON table1.id = table3.t1_id
LEFT JOIN
table4 ON table1.id = table4.t1_id
LEFT JOIN
table5 ON table1.id = table5.t1_id
WHERE
(table1.created_at >= '02-02-2015' AND table1.created_at <= '02-05-2015')
GROUP BY c_date
ORDER BY c_date desc
Is there actually a way to get what I want with a join? The query is so expensive it times out.
I am using postgres and rails, all of these are associated with models and associations.
UPDATE Testing Andrews comment got query plan
Unique (cost=1062356.31..1062384.74 rows=2843 width=16)
-> Sort (cost=1062356.31..1062363.42 rows=2843 width=16)
Sort Key: (date_trunc('day'::text, table1.created_at)), (count(table1.id)), (count(table1_1.id))
-> HashAggregate (cost=1062157.68..1062193.22 rows=2843 width=16)
-> Merge Right Join (cost=0.58..1062136.35 rows=2845 width=16)
Merge Cond: (table1_1.id = table1.id)
-> GroupAggregate (cost=0.29..1059054.94 rows=41399 width=4)
-> Nested Loop (cost=0.29..756842.24 rows=60359742 width=4)
-> Index Only Scan using table1_pkey on table1 table1_1 (cost=0.29..2314.24 rows=41399 width=4)
-> Materialize (cost=0.00..34.87 rows=1458 width=0)
-> Seq Scan on table2 (cost=0.00..27.58 rows=1458 width=0)
-> Index Scan using table1_pkey on table1 (cost=0.29..2521.24 rows=2845 width=12)
Filter: ((created_at >= '2015-02-02 00:00:00'::timestamp without time zone) AND (created_at <= '2015-02-05 00:00:00'::timestamp without time zone))