MySQL Sum不正确并加入

时间:2012-10-24 13:42:49

标签: mysql sql aggregate-functions

我正在构建一个度假系统,其中一个功能是能够购买额外的假期,你可以在一年中的几个点做,所以我想看看假日的总天数,已预订多少以及每位用户购买了多少。

我正在进行查询

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

现在,这会让天卒之类栏目中的结果高于我的预期,这很奇怪,因为当我摆脱总和并且只有hr_buyback.days它会显示我所期望的所有个人价值观(除了我而且他们被总结了)

其次,在MySQL中,您可以在MSSQL中做到这一点

left outer join hr_buyback on (select hr_buyback.user_id where buy_sell = 'buy') = hr_leave.user_id

相关的表定义(我假设这是你的意思?):

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   

1 个答案:

答案 0 :(得分:2)

问题可能是hr_buyback中每个匹配行的hr_leave行的每一行都会得到一份副本。

我假设每个用户可以拥有多个hr_buyback行,并且可以拥有hr_buyback行但没有hr_leave行。如果是这样,你可能会想要这样的东西:

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