Reputation: 5
I have a table with a PersonID, TeamID, and DateEffective. I'd like to return the earliest date that each person changed team. It is possible that a person can move back into a team they were previously allocated to.
Create Table PHistory
(PersonID INT,
TeamID VARCHAR(8),
DateEffective datetime)
Insert INTO PHistory
Values (1, 'TeamA', '2017-07-01'),
(1, 'TeamA', '2017-07-02'),
(1, 'TeamB', '2017-07-03'),
(1, 'TeamA', '2017-07-04'),
(2, 'TeamA', '2017-07-01'),
(2, 'TeamA', '2017-07-02'),
(2, 'TeamA', '2017-07-03'),
(2, 'TeamA', '2017-07-04')
I'd like the query to return:
I've messed around with MIN() but it doesn't cope with the fact that people can move back into old teams.
I've seen this post that uses a window function, but it only returns the latest record and I need to see all team changes (I couldn't see how to adapt it to my needs).
Upvotes: 0
Views: 24
Reputation: 4146
Here is one approach using row_number
select
PersonId, minDate = min(DateEffective)
from (
select
*, rn1 = row_number() over (partition by PersonId order by DateEffective)
, rn2 = row_number() over (partition by PersonId, TeamId order by DateEffective)
from
PHistory
) t
group by PersonId, rn1 - rn2
order by 1,2
Output
1 2017-07-01 00:00:00.000
1 2017-07-03 00:00:00.000
1 2017-07-04 00:00:00.000
2 2017-07-01 00:00:00.000
Upvotes: 1