Search code examples
sqlsql-serverleft-joininner-join

SQL Server stored procedure doubling all values


This is my stored procedure and it seems to be pulling all the correct values from the table but for some reason it is doubling all the hours which is in turn doubling all values. I have no idea where I'm going wrong here, any help would be much appreciated.

SELECT  
    FirstName, LastName,
    JobRegular.RegularHours AS RegularHours,
    JobRegular.RegularHours * dbo.Employees.Wage AS RegularPay,
    JobRegular.OvertimeHours AS OvertimeHours,
    JobRegular.OvertimeHours * dbo.Employees.Wage AS OvertimePay,
    JobOvertime.CBRegularHours AS CBRegularHours,
    JobOvertime.CBRegularHours * dbo.Employees.Wage AS CBRegularPay,
    JobOvertime.CBOvertimeHours AS CBOvertimeHours,
    JobOvertime.CBOvertimeHours * dbo.Employees.Wage AS CBOvertimePay
FROM 
    dbo.Employees
INNER JOIN 
    (SELECT  
         dbo.EmployeeJobs.EmployeeId,
         SUM(dbo.EmployeeJobs.RegularHours) AS RegularHours,
         SUM(dbo.EmployeeJobs.RegularHours) * MIN(dbo.Employees.Wage) AS RegularPay,
         SUM(dbo.EmployeeJobs.OvertimeHours) As OvertimeHours, 
         SUM(dbo.EmployeeJobs.OvertimeHours) * MIN(dbo.Employees.Wage) As OvertimePay
     FROM 
         dbo.EmployeeJobs, dbo.Employees
     WHERE 
         dbo.EmployeeJobs.ComputerCodeId IN (7,8,9,13,14,15,16,17,18,19,22)
     GROUP BY 
         dbo.EmployeeJobs.EmployeeId) AS JobRegular ON dbo.Employees.EmployeeId = JobRegular.EmployeeId 
LEFT JOIN 
    (SELECT  
         dbo.EmployeeJobs.EmployeeId,
         SUM(dbo.EmployeeJobs.RegularHours) As CBRegularHours,
         SUM(dbo.EmployeeJobs.RegularHours) * MIN(dbo.Employees.Wage) AS CBRegularPay,
         SUM(dbo.EmployeeJobs.OvertimeHours) AS CBOvertimeHours,
         SUM(dbo.EmployeeJobs.OvertimeHours) * MIN(dbo.Employees.Wage) As CBOvertimePay
     FROM  
         dbo.EmployeeJobs, dbo.Employees
     WHERE 
         dbo.EmployeeJobs.ComputerCodeId IN (4,5,6)
     GROUP BY 
         dbo.EmployeeJobs.EmployeeId) AS JobOvertime ON dbo.Employees.EmployeeId = JobOvertime.EmployeeId 

Solution

  • Your sub queries (JobRegular, JobOvertime) have no join conditions - you are saying join EmployeeJobs to Employees, but haven't said how. So it does a cross join - every employee record joins with every jobs record. I'm surprised it's only doubling. You need something more like this - this is JobRegular, JobOvertime also needs fixing. (Also, start using table aliases, it will make this much more readable)

    SELECT  dbo.EmployeeJobs.EmployeeId,
            SUM(dbo.EmployeeJobs.RegularHours) AS RegularHours,
            SUM(dbo.EmployeeJobs.RegularHours) * MIN(dbo.Employees.Wage) AS RegularPay,
            Sum(dbo.EmployeeJobs.OvertimeHours) As OvertimeHours, 
            SUM(dbo.EmployeeJobs.OvertimeHours) * MIN(dbo.Employees.Wage) As OvertimePay
    FROM dbo.EmployeeJobs 
        inner join dbo.Employees on dbo.Employees.EmployeeId = dbo.EmployeeJobs.EmployeeId
    WHERE dbo.EmployeeJobs.ComputerCodeId IN (7,8,9,13,14,15,16,17,18,19,22)
    GROUP BY dbo.EmployeeJobs.EmployeeId
    

    Edited - actually, you don't need employee in the subquery at all, remove it

    SELECT  dbo.EmployeeJobs.EmployeeId,
            SUM(dbo.EmployeeJobs.RegularHours) AS RegularHours,
            SUM(dbo.EmployeeJobs.RegularHours) * MIN(dbo.Employees.Wage) AS RegularPay,
            Sum(dbo.EmployeeJobs.OvertimeHours) As OvertimeHours, 
            SUM(dbo.EmployeeJobs.OvertimeHours) * MIN(dbo.Employees.Wage) As OvertimePay
    FROM dbo.EmployeeJobs 
    WHERE dbo.EmployeeJobs.ComputerCodeId IN (7,8,9,13,14,15,16,17,18,19,22)
    GROUP BY dbo.EmployeeJobs.EmployeeId