Reputation: 109
Back with another SQL question about joins. I have 3 tables:
user: id, username, name, city, state, private
rides: id, creator, title, datetime, city, state
posts: id, title, user, date, state, city
I need to get the users from the user table, and based on the id of user, get the number of posts and rides for each person. Such as, user with id 25 has 2 rides and 4 posts, while the user with id 27 has 2 rides and 2 posts. The problem I am having, is that both users are coming back with 4 posts and rides each.
user.id = rides.creator = posts.user //just so you know what fields equals the user id
Here is my code:
select u.id, u.username, u.state, u.city, count(p.id) as TotalPosts, count(r.id) as TotalRides
from user u
left join posts p on p.user=u.id
left join rides r on r.creator=u.id
where private='public'
group by u.id
order by u.username, u.state asc;
If I separate them out, and just join the posts or the rides, I get the correct totals back. I tried switching the order of the joins, but I got the same results. Not sure what is going on.
Any ideas or thoughts are appreciated.
Upvotes: 1
Views: 213
Reputation: 943
you can always use a sub select.
select u.*,
(select count(*) from posts where user = u.id) as 'posts',
(select count(*) from rides where creator = u.id) as 'rides'
from users u
where .....
Upvotes: 0
Reputation: 1271191
Your problem is a Cartesian product along two different dimensions. The best solution is to pre-aggregate the data:
select u.id, u.username, u.state, u.city, p.TotalPosts, r.TotalRides
from user u left join
(select user, count(*) as totalposts
from posts p
group by user
) p
on p.user = u.id left join
(select creator, count(*) as totalrides
from rides r
group by creator
) r
on r.creator = u.id
where u.private = 'public'
group by u.id
order by u.username, u.state asc;
Upvotes: 1