Reputation: 938
I'm building a holiday system and one of the features is being able to buy extra holiday which you can do at several points of the year, so I'm wanting to see the total number of days holiday, how much has been booked and how much has been bought by each user.
I'm doing a query
SELECT hr_user.name AS username,
hr_user.user_id,
SUM(working_days) AS daysbooked,
sum(hr_buyback.days) AS daysbought
FROM hr_leave
inner join hr_user on hr_user.user_id = hr_leave.user_id
left outer join hr_buyback on hr_buyback.user_id = hr_user.user_id
where active = 'y'
and hr_leave.start_date between '2012-01-01' and '2012-12-31'
and (hr_leave.status = 'approved' OR hr_leave.status = 'pending')
GROUP BY hr_user.name, hr_user.user_id
Now this is bringing back results in the daysbought column waaaay higher than what I was expecting, which is odd because when I get rid of the sum and just have hr_buyback.days it shows all the individual values I'd expect (except I'd much rather they were summed)
Secondly, in MySQL can you do what you can in MSSQL which is
left outer join hr_buyback on (select hr_buyback.user_id where buy_sell = 'buy') = hr_leave.user_id
?
Relevant table definitions (I assume this is what you mean?):
hr_buyback
buyback_id int(11) NO PRI auto_increment
user_id int(11) NO
days int(11) NO
buy_sell varchar(10) NO
status varchar(10) NO pending
year int(11) NO
hr_user
user_id int(11) NO PRI auto_increment
name varchar(40) NO
email varchar(40) NO UNI
level int(5) YES
manager_id int(11) NO
team_id int(11) YES
active varchar(2) NO y
holidays_day int(11) NO
start_date timestamp NO CURRENT_TIMESTAMP
password varchar(60) NO
division_id int(11) YES
day_change int(5) NO 0
priv_hours varchar(2) NO n
po_level int(2) YES 0
po_signoff int(10) YES
hr_leave
leave_id int(11) NO PRI auto_increment
user_id int(11) NO
start_date date NO
end_date date NO
day_type varchar(10) NO
status varchar(20) NO pending
working_days varchar(5) NO
leave_type int(11) NO
cancel int(11) NO 0
date timestamp NO CURRENT_TIMESTAMP
Upvotes: 1
Views: 221
Reputation: 36
The problem is probably that you will get one copy of each row from hr_buyback
for each matching row in hr_leave
.
I assume that it is possible to have more than one hr_buyback
row per user, and that it is possible to have a hr_buyback
row without a hr_leave
row. If so, you'll probably want something like this:
SELECT hr_user.name AS username,
hr_user.user_id,
SUM(working_days) AS daysbooked,
(SELECT SUM(days)
FROM hr_buyback
WHERE hr_buyback.user_id = hr_user.user_id) AS daysbought
FROM hr_user
left join hr_leave on hr_user.user_id = hr_leave.user_id
where active = 'y'
and hr_leave.start_date between '2012-01-01' and '2012-12-31'
and (hr_leave.status = 'approved' OR hr_leave.status = 'pending')
GROUP BY hr_user.name, hr_user.user_id
Upvotes: 2