I have three tables and am trying to get info from two and then perform a calculation on the third and display all the results in one query.
The (simplified) tables are:
table: employee_work
employee_id name
1 Joe
2 Bob
3 Jane
4 Michelle
table: carryover
employee_id days
1 5
2 10
3 3
table: timeoff
employee_id time_off_type days
1 Carryover 2
1 Leave 3
1 Carryover 1
2 Sick 4
2 Carryover 4
3 Leave 1
4 Sickness 4
The results I would like are:
employee_id, carryover.days, timeoff.days
1 5 3
2 10 4
3 3 0
However when I run the query, whilst I get the correct values in columns 1 and 2, I get the same number repeated in the third column for all entries.
Here is my query:
Select
employee_work.employee_id,
carryover.carryover,
(SELECT SUM(days) FROM timeoff WHERE timeoff.time_off_type = 'Carryover'
AND timeoff.start_date>='2013-01-01') AS taken
From
carryover Left Join
employee_work On employee_work.employee_id = carryover.employee_id Left Join
timeoff On employee_work.employee_id = timeoff.employee_id Left Join
Where
carryover.carryover > 0
Group By
employee_work.employee_id
I have tried to group by in the sub query but I then get told "Subquery returns more than one row" - how can I ensure that the sub query is respecting the join so it only looks at each employee at a time so I get my desired results?
The answer to your question is to use a correlated subquery. You don't need to mention the timeoff
table twice in this case:
Select
employee_work.employee_id,
carryover.carryover,
(SELECT SUM(days)
FROM timeoff
WHERE timeoff.time_off_type = 'Carryover' and
timeoff.start_date>='2013-01-01' and
timeoff.employee_id = employee_work.employee_id
) AS taken
From
carryover Left Join
employee_work On employee_work.employee_id = carryover.employee_id
Where
carryover.carryover > 0
Group By
employee_work.employee_id;
An alternative structure is to do the grouping for all employees in the from
clause. You can also remove the employee_work
table, because it does not seem to be being used. (You can use carryover.employee_id
for the id.)
Select co.employee_id, co.carryover, et.taken
From carryover c Left Join
(SELECT employee_id, SUM(days) as taken
FROM timeoff
WHERE timeoff.time_off_type = 'Carryover' and
timeoff.start_date>='2013-01-01'
) et
on co.employee_id = et.employee_id
Where c.carryover > 0;
I don't think the group by
is necessary. If it is, then you should probably have an aggregation function in the original query.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.