Reputation: 2095
i want to join two record (from same table) into one row with multiple column.
employment history structure as follows:
StaffID StartDate EndDate DeptID
==================================================
1 2010-10-01 2011-01-19 1
1 2011-01-20 2012-12-31 2
1 2013-01-01 2013-05-29 4
how can i join the two rows into one row if same StaffID and the 2nd record startdate is 1 day after the enddate of 1st record (continuous employment)
the output should like this
StaffID EffectiveDate New_DeptID Prev_DeptID
==================================================
1 2011-01-20 2 1
1 2013-01-01 4 2
the following is my sql statement but it doesn't work
select distinct
ca1.StaffID,
ca1.ProjectDepartment as Prev_DeptID, ca1.StartDate, ca1.EndDate,
ca2.ProjectDepartment as New_DeptID, ca2.StartDate, ca2.EndDate
from
emp_hist as ca1,
emp_hist as ca2
where
(ca1.StaffID = ca2.StaffID)
and ca1.StartDate<>ca2.StartDate
and ca1.EndDate <>ca2.EndDate
and ca2.startdate= DATEADD(day, 1, ca1.enddate)
for example, two records (true data) in the table:
StaffID StartDate EndDate DeptID
===========================================================================
1 2010-04-12 12:00:00.000 2013-02-28 00:00:00.000 1
1 2013-03-01 12:00:00.000 2013-08-29 11:02:59.877 2
i cannot retrieve this record by using my sql statement
Upvotes: 2
Views: 8162
Reputation: 1269563
Your problem is that the dates have a time component. You appear to be using SQL Server. You can fix your query by doing this:
select ca1.StaffID,
ca1.ProjectDepartment as Prev_DeptID, ca1.StartDate, ca1.EndDate,
ca2.ProjectDepartment as New_DeptID, ca2.StartDate, ca2.EndDate
from emp_hist as ca1 join
emp_hist as ca2
on ca1.StaffID = ca2.StaffID and
cast(ca1.StartDate as date) <> cast(ca2.StartDate as date) and
cast(ca1.EndDate as date) <> cast(ca2.EndDate as date) and
cast(ca2.startdate as date) = DATEADD(day, 1, cast(ca1.enddate as date));
I also replaced the implicit join with improved join syntax.
Upvotes: 1
Reputation: 1598
If you're using SQL 2012 try the lag functions.
select distinct
ca1.StaffID,
ca1.EndDate,
ca1.ProjectDepartment as New_DeptID,
LAG(ca1.ProjectDepartment) OVER (PARTITION BY ca1.StaffId ORDER BY ca1.EndDate) as Prev_DeptID
from
emp_hist as ca1
If you're not, use the RANK function and a subquery
select
eh.StaffID,
eh.EndDate,
eh.ProjectDepartment as New_DeptID,
eh1.ProjectDepartment as Prev_DeptID
from
(select *, RANK(EndDate) OVER (PARTITION BY StaffId ORDER BY EndDate) as Rank
from emp_hist) eh left join (
select distinct
StaffID,
EndDate,
ProjectDepartment,
RANK(EndDate) OVER (PARTITION BY StaffId ORDER BY EndDate) as Rank
from
emp_hist) eh1 on eh1.staffid=a.staffid and eh1.rank=eh.rank-1
Upvotes: 1