Click here to Skip to main content
15,881,812 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have the following tables Employee, EmployeeManager, EmployeeLeavesAssigned, EmployeeLeavesTaken, EmployeeLeaveCashed

Employee 1 to Many EmployeeManager (One employee can have multiple managers)
Employee 1 to Many EmployeeLeavesAssigned (one record for each employee per calendar year)
Employee 1 to Many EmployeeLeavesTaken (multiple records for each employee per calendar year)
Employee 1 to Many EmployeeLeaveCashed (multiple records for each employee per calendar year)

Now when I am trying create a SP to get list all leaves cashed by employees
it gives me duplicate row for each record in the EmployeeLeaveCashed because of the EmployeeManager table

I am using left join and the left table is EmployeeLeaveCashed and right tables are Employee & Employee Manager. Even distinct does not help.

What should I do to eliminate this duplicate row.

Here is the query
SELECT
ED.RefEmpID AS [EmpID]
,ED.EmpFirstName
,ED.EmpMiddleName
,ED.EmpLastName
,EMG.RefEMGID AS [ManagerID]
,ELC.RefELCID AS [ELCID]
,ELC.CashedDate
,ELC.CashedCount
,ELC.RefCalendarPeriodID AS [APID]
,ELC.PeriodStartDate
,ELC.PeriodEndDate
,LTY.RefLeaveTypeID AS [LTYID]
,LTY.LeaveTypeName
FROM EmployeeLeaveCashed ELC
LEFT JOIN CalendarPeriod CP ON ELC.RefCalendarPeriod = CP.RefCalendarPeriod
LEFT JOIN LeaveType LTY ON ELC.RefLeaveTypeID = LTY.RefLeaveTypeID
LEFT JOIN Employee ED ON ELC.RefEmpID = ED.RefEmpID
LEFT JOIN EmployeeManager EMG ON ED.RefEmpID = EMG.RefEmpID

What I have tried:

I removed the EmployeeManager table from the join. But I need to show the Manager name. So I need to have in the SP.
Posted
Updated 27-Feb-20 20:32pm
v2
Comments
Jörgen Andersson 28-Feb-20 1:29am    
Can you show us the query?
Christopher Fernandes 28-Feb-20 1:40am    
SELECT
ED.RefEmpID AS [EmpID]
,ED.EmpFirstName
,ED.EmpMiddleName
,ED.EmpLastName
,EMG.RefEMGID AS [ManagerID]
,ELC.RefELCID AS [ELCID]
,ELC.CashedDate
,ELC.CashedCount
,ELC.RefCalendarPeriodID AS [APID]
,ELC.PeriodStartDate
,ELC.PeriodEndDate
,LTY.RefLeaveTypeID AS [LTYID]
,LTY.LeaveTypeName
FROM EmployeeLeaveCashed ELC
LEFT JOIN CalendarPeriod CP ON ELC.RefCalendarPeriod = CP.RefCalendarPeriod
LEFT JOIN LeaveType LTY ON ELC.RefLeaveTypeID = LTY.RefLeaveTypeID
LEFT JOIN Employee ED ON ELC.RefEmpID = ED.RefEmpID
LEFT JOIN EmployeeManager EMG ON ED.RefEmpID = EMG.RefEmpID
Maciej Los 28-Feb-20 1:58am    
Please, use Improve Question[^] widget and add above content.

I'm pretty sure it's your DB design that tripping you up - it doesn't sound right at all.
In particular:
Employee 1 to Many EmployeeManager (One employee can have multiple managers)
Seems wrong: an employee will normally have one manager, a manager will manage multiple employees.
Similarly:
Employee 1 to Many EmployeeLeavesAssigned (one record for each employee per calendar year)
Employee 1 to Many EmployeeLeavesTaken (multiple records for each employee per calendar year)
Employee 1 to Many EmployeeLeaveCashed (multiple records for each employee per calendar year)
Doesn't sound right either.
I'd suggest that Managers have Employees; Employees have YearlyLeaveRecords; LeaveBooked have YearlyLeaveRecords; LeaveTaken have YearlyLeaveRecords - this would reflect the "real world" situation far better, and will probably get rid of the problem.

So Employees have a Foreign Key to Managers; YearlyLeaveRecords have a Foreign Key to Employees; LeaveBooked and LeaveTaken have Foreign Keys to YearlyLeaveRecords.
 
Share this answer
 
Comments
Stefan_Lang 28-Feb-20 2:52am    
Apart from my difficulty in understanding what assigned/taken/cashed* is supposed to mean, I think your suggestion makes a lot more sense.

*: when I think about it, the corresponding german terms used in our administration are also not very intuitive ;-p

P.S.: have a 5
Well the problem is obviously that there might be more than one manager per employee.

So either you have to decide for a main manager for every employee which will need some changes to the database.
Or you have denormalize the query and show all managers in row. If you comma separate them it will look similar to this:
SQL
SELECT  ED.RefEmpID AS [EmpID]
       ,ED.EmpFirstName
       ,ED.EmpMiddleName
       ,ED.EmpLastName
       ,EMG.RefEMGID AS [ManagerID]
       ,COALESCE(
            STUFF
                (
                  (
                    SELECT  ', ' + EMG.RefEMGID
                      FROM  EmployeeManager EMG
                      WHERE ELC.RefEmpID = ED.RefEmpID
                      FOR XML PATH('')
                  ), 1, 2, N''
                )
            , N'') AS ManagerIDs
       ,ELC.RefELCID AS [ELCID]
       ,ELC.CashedDate
       ,ELC.CashedCount
       ,ELC.RefCalendarPeriodID AS [APID]
       ,ELC.PeriodStartDate
       ,ELC.PeriodEndDate
       ,LTY.RefLeaveTypeID AS [LTYID]
       ,LTY.LeaveTypeName
FROM    EmployeeLeaveCashed ELC
LEFT JOIN CalendarPeriod CP ON ELC.RefCalendarPeriod = CP.RefCalendarPeriod
LEFT JOIN LeaveType LTY ON ELC.RefLeaveTypeID = LTY.RefLeaveTypeID
LEFT JOIN Employee ED ON ELC.RefEmpID = ED.RefEmpID
Adjust as necessary.
 
Share this answer
 
v2
Comments
Stefan_Lang 28-Feb-20 2:54am    
Good try, but I think Originalgriff (solution 2) nailed it: the relations are wrong.
Jörgen Andersson 28-Feb-20 3:00am    
No, it's quite possible to have more than one manager. For example one department manager at the same time as you have one or more project managers.
To handle it properly you obviously need a different db-structure though.
Stefan_Lang 28-Feb-20 3:05am    
I've thought of that, but am still convinced it makes no sense to model it this way. The administrative relation is only to your department manager, not to your project managers. If you want to model the relations regarding projects in your DB, then you need to set up a project table with a 1:1 relation for the project manager, and 1:N relation for the team members.
You've got what you asked for: the Select fields contain fields from the EmployeeManager and from the Employee tables. Of course you will have multiple entries per Employee!

If you don't actually need the EMG fields, drop that join and the accompanying fields. If you only want to see data from one specific Manager, then you need to specify a condition to select the one manager that you want. Otherwise your output is what you asked for.

P.S.: Like Originalgriff said in solution 2, you probably modeled your manager relation upside down. Changing that should resolve the issue.
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900