Reputation: 10740
I have three tables:
user(id, name);
tasks(id, user_id, text, date);
bonus(id, user_id, sum, date, type).
I'm trying to write a query that will give me a list of all users, quantity of their tasks and a sum of bonuses of every type, each in separate column.
There are three types of bonuses:
type = (1, 2, 3)
So, I mean a table, which looks like this
name | task_count | bonus_1 | bonus_2 | bonus_3
Upvotes: 1
Views: 250
Reputation: 238048
Consider doing the aggregation before joining on user
. For example:
select u.name
, t.task_count
, b.bonus_1
, b.bonus_2
, b.bonus_3
, t.comment_count
from user u
left join
(
select user_id
, count(distinct t.id) as task_count
, count(distinct c.id) as comment_count
from tasks t
left join
comment c
on c.task_id = t.id
group by
t.user_id
) t
on t.user_id = u.id
left join
(
select user_id
, sum(case when type = 1 then sum end) as bonus_1
, sum(case when type = 2 then sum end) as bonus_3
, sum(case when type = 3 then sum end) as bonus_2
from bonus
group by
user_id
) b
on b.user_id = u.id
Upvotes: 0
Reputation: 34177
NOTE: the following won't work! Retained for information
SELECT
user.name,
COUNT(tasks.id) AS task_count,
SUM(bonus1.sum) AS bonus_1,
SUM(bonus2.sum) AS bonus_2,
SUM(bonus3.sum) AS bonus_3
FROM user
LEFT OUTER JOIN tasks ON tasks.user_id = user.id
LEFT OUTER JOIN bonus1 ON bonus1.user_id = user.id
AND bonus1.type = 1
LEFT OUTER JOIN bonus2 ON bonus2.user_id = user.id
AND bonus1.type = 2
LEFT OUTER JOIN bonus3 ON bonus3.user_id = user.id
AND bonus1.type = 3
GROUP BY
user.name
ORDER BY
user.name
You might need to handle NULL
values specially if it is not the case that every user will always have at least one task and at least one of each type of bonus.
Upvotes: 0
Reputation: 452977
SELECT u.name,
t.task_count,
SUM(CASE WHEN b.type=1 then b.sum END) AS bonus_1,
SUM(CASE WHEN b.type=2 then b.sum END) AS bonus_2,
SUM(CASE WHEN b.type=3 then b.sum END) AS bonus_3
FROM user u
LEFT JOIN (SELECT user_id, COUNT(*) AS task_count
FROM tasks
GROUP BY user_id) t ON t.user_id = u.id
LEFT JOIN bonus b ON b.user_id = u.id
GROUP BY u.id,u.name,t.task_count
Upvotes: 1