I'm using SQL Server 2012 and have something like this:
Employee Position Month
------------------------------
John A 1
John A 2
John A 3
John A 4
John A 5
John A 6
John B 7
John B 8
John B 9
John B 10
John B 11
John B 12
John B 13
John C 14
John C 15
John C 16
John C 17
John C 18
John C 19
John C 20
John A 21
John A 22
John A 23
John A 24
John A 25
John A 26
And I need the same table, but with two additional columns with the starting and finishing month, like this:
Employee Position Month Begins Ends
--------------------------------------------
John A 1 1 6
John A 2 1 6
John A 3 1 6
John A 4 1 6
John A 5 1 6
John A 6 1 6
John B 7 7 13
John B 8 7 13
John B 9 7 13
John B 10 7 13
John B 11 7 13
John B 12 7 13
John B 13 7 13
John C 14 14 20
John C 15 14 20
John C 16 14 20
John C 17 14 20
John C 18 14 20
John C 19 14 20
John C 20 14 20
John A 21 21 26
John A 22 21 26
John A 23 21 26
John A 24 21 26
John A 25 21 26
John A 26 21 26
I tried to do something like:
SELECT
[Employee]
,[Position]
,[Month]
,MIN([Month]) OVER (PARTITION BY [Employee], [Position]) AS 'Begins'
,MAX([MONTH]) OVER (PARTITION BY [Employee], [Position]) AS 'Ends'
FROM
tab
ORDER BY
[Month]
but if so, we can't say the difference between the first set on "Position A" (1 to 6) and the second set (21 to 26), and the result displays every row where Position = "A" with "Begins = 1" and "Ends = 26", which is undesirable.
I'm trying to do that without using a recursive CTE, because the actual query is very long and the tables used are very large, so I'm avoiding that mainly for performance, but I don't know if that is possible
Use the difference of row numbers approach to classify consecutive rows with same employee and position into a group.
select t.*,
row_number() over(partition by employee order by [month])
- row_number() over (partition by employee, position order by [month]) as grp
from tbl t
Then get the max and min of each grp.
select employee,position,month,
min(month) over(partition by employee,position,grp) as begins,
max(month) over(partition by employee,position,grp) as ends
from (select t.*,
row_number() over(partition by employee order by [month])
- row_number() over (partition by employee, position order by [month]) as grp
from tbl t
) t
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.