I have written a query to generate payroll based on attendance for a month, for about 4000 employees. It takes quite a long time to execute. Basically, what I am doing is to joining two different queries using a common key for a single line of output per employee. But some blog suggests that UNION on this type of join would perform better. Is there any way to reduce time with my current query, or would UNION help?
DECLARE @EmployeePayrollDataTable AS TABLE (EmployeeId int,LegalOverTime int,ExtraOverTime int,ToatalOverTime int,OK int,LateDays int,
AbsentDays int, LeaveDays int, HolidayOffdays int,BasicPay decimal,GrossPay decimal,HouseRent decimal,MedicalFoodTransportCost decimal,
BasicPayRate decimal,GrossPayRate decimal,OverTimeRate float,AttendanceBonus decimal,StampDeduction decimal);
DECLARE @EmployeePayrollTable AS TABLE (EmployeeId int,BasicSalary decimal,HouseRent decimal,MedicalFoodTransportCost decimal,GrossSalary decimal, TotalPresents int,
HolidayOffdays int, LeaveDays int,AbsentDays int, TotalDeduction decimal, TotalSalary decimal, AttendanceBonus decimal, OvertimeHours int, OvertimeRate float,
OvertimeAmount decimal, StampCharge decimal, FinalSalary decimal)
INSERT INTO @EmployeePayrollDataTable
SELECT A.EmployeeId,A.LegalOverTime,A.ExtraOverTime,A.ToatalOverTime,A.OK,A.LateDays,A.AbsentDays,A.LeaveDays,A.HolidayOffdays,
B.BasicPay,B.GrossPay,B.HouseRent,B.MedicalFoodTransportCost,B.BasicPayRate,B.GrossPayRate,B.OverTimeRate,B.AttendanceBonus,B.StampDeduction FROM
(SELECT TT.EmployeeId,
SUM(TT.LegalOverTime) AS LegalOverTime,
SUM(TT.ExtraOverTime) AS ExtraOverTime,
SUM(TT.LegalOverTime)+SUM(TT.ExtraOverTime) AS ToatalOverTime,
ISNULL(COUNT(OK), 0 ) OK,
ISNULL(COUNT(LateDays), 0 ) LateDays,
ISNULL(COUNT(AbsentDays), 0 ) AbsentDays,
ISNULL(COUNT(LeaveDays), 0 ) LeaveDays,
ISNULL(COUNT(HolidayOffdays), 0 ) HolidayOffdays
FROM
(SELECT HAH.EmployeeId,
CASE WHEN HAH.AttendanceStatus!=5 OR HAH.AttendanceStatus!=6 THEN
CASE WHEN HAH.PayableOverTime<=2 THEN HAH.PayableOverTime
WHEN HAH.PayableOverTime>2 THEN 2
ELSE 0
END
ELSE 0
END AS LegalOverTime,
CASE WHEN HAH.AttendanceStatus!=5 OR HAH.AttendanceStatus!=6 THEN
CASE WHEN HAH.PayableOverTime<=2 THEN 0
WHEN HAH.PayableOverTime>2 THEN HAH.PayableOverTime-2
ELSE 0
END
ELSE HAH.PayableOverTime
END AS ExtraOverTime,
CASE WHEN
(AttendanceStatus=1 and HAH.[Status]=1) THEN AttendanceStatus END AS OK,
CASE WHEN
(AttendanceStatus=2 and HAH.[Status]=1) THEN AttendanceStatus END AS LateDays,
CASE WHEN
(AttendanceStatus=3 and HAH.[Status]=1) THEN AttendanceStatus END AS AbsentDays,
CASE WHEN
(AttendanceStatus=4 and HAH.[Status]=1) THEN AttendanceStatus END AS LeaveDays,
CASE WHEN
((AttendanceStatus=5 or AttendanceStatus=6) and HAH.[Status]=1) THEN AttendanceStatus END AS HolidayOffdays
FROM HRMS_Attendance_History as HAH
JOIN HRMS_Employee HE on HAH.EmployeeId=HE.ID
WHERE HE.Present_Status=1 and CAST(HE.Joining_Date as Date)<='2019-04-01' and CAST([Date] as Date)>='2019-04-01' and CAST([Date] as Date)<='2019-04-30') TT
GROUP BY TT.EmployeeId) A
JOIN
(SELECT
T.EmployeeId,
ISNULL(SUM(BasicPay), 0 ) BasicPay,
ISNULL(SUM(GrossPay), 0 ) GrossPay,
ISNULL(SUM(HouseRent), 0 ) HouseRent,
ISNULL(SUM(MedicalFoodTransportCost), 0 ) MedicalFoodTransportCost,
ISNULL(SUM(BasicPay)/30, 0 ) BasicPayRate,
ISNULL(SUM(GrossPay)/30, 0 ) GrossPayRate,
ISNULL(SUM(OverTimeRate), 0 ) OverTimeRate,
ISNULL(SUM(AttendanceBonus), 0 ) AttendanceBonus,
ISNULL(SUM(StampDeduction), 0 ) StampDeduction
FROM (SELECT EmployeeId,
CASE WHEN
(Eod_RefFk=1 and er.[Status]=1) THEN ActualAmount END AS BasicPay,
CASE WHEN
((Eod_RefFk=1 or Eod_RefFk=2 or Eod_RefFk=3) and er.[Status]=1) THEN ActualAmount END AS GrossPay,
CASE WHEN
(Eod_RefFk=2 and er.[Status]=1) THEN ActualAmount END AS HouseRent,
CASE WHEN
(Eod_RefFk=3 and er.[Status]=1) THEN ActualAmount END AS MedicalFoodTransportCost,
CASE WHEN
(Eod_RefFk=11 and er.[Status]=1) THEN ActualAmount END AS OverTimeRate,
CASE WHEN
(Eod_RefFk=7 and er.[Status]=1) THEN ActualAmount END AS AttendanceBonus,
CASE WHEN
(Eod_RefFk=12 and er.[Status]=1) THEN ActualAmount END AS StampDeduction
FROM HRMS_EodRecord er JOIN HRMS_Employee e on er.EmployeeId=e.ID WHERE e.Present_Status=1 and CAST(e.Joining_Date as Date)<='2019-04-01') t
group by t.EmployeeId) B ON A.EmployeeId=B.EmployeeId
INSERT INTO @EmployeePayrollTable
SELECT EmployeeId,
BasicPay,
HouseRent,
MedicalFoodTransportCost,
GrossPay,
(OK+LateDays+LeaveDays+HolidayOffdays),
HolidayOffdays,
LeaveDays,
AbsentDays,
AbsentDays*BasicPayRate,
GrossPay-(AbsentDays*BasicPayRate),
CASE WHEN AbsentDays>0 or LeaveDays>0 or LateDays>2 THEN 0
ELSE AttendanceBonus END AS AttendanceBonus,
LegalOverTime,
OverTimeRate,
LegalOverTime*OverTimeRate,
StampDeduction,
CASE WHEN AbsentDays>0 or LeaveDays>0 or LateDays>2 THEN(LegalOverTime*OverTimeRate)+(GrossPay-(AbsentDays*BasicPayRate))-StampDeduction
ELSE (LegalOverTime*OverTimeRate)+(GrossPay-(AbsentDays*BasicPayRate)+AttendanceBonus)-StampDeduction END AS OvertimeAmount
FROM @EmployeePayrollDataTable
select * from @EmployeePayrollTable