Reputation: 43
I am not sure how to word this but I have Start
and End
times in separate rows, and I want to merge them into a single a row. In this sample data, it's basically tracking/logging project times:
Project Type Time
A Start 1:00
A End 1:10
B Start 2:00
B End 2:10
B Start 2:30
B End 2:45
C End 3:00
D Start 3:10
D End 3:20
What I am looking for is something like this:
Project Start End
A 1:00 1:10
B 2:00 2:10
B 2:30 2:45
C NULL 1:10
D 3:10 3:20
The 2 parts that are odd are that:
Can anyone point me in the right direction? I couldn't find anything on Stackoverflow that had these same requirements.
Upvotes: 3
Views: 1414
Reputation: 222512
This is some kind of gaps-and-island problem.
I would approach this with lag()
and a window sum()
. A new group starts everytime consecutive records types are not 'Start'
followed by an 'End'
.
select
project,
min(case when type = 'Start' then time end) Start,
max(case when type = 'End' then time end) [End]
from (
select
t.*,
sum(case when type = 'End' and lag_type = 'Start' then 0 else 1 end)
over(partition by project order by time) grp
from (
select
t.*,
lag(type) over(partition by project order by time) lag_type
from mytable t
) t
) t
group by project, grp
order by project, grp
Project | Start | End :------ | :---- | :--- A | 1:00 | 1:10 B | 2:00 | 2:10 B | 2:30 | 2:45 C | null | 3:00 D | 3:10 | 3:20
Upvotes: 3
Reputation: 521599
We can try using pivoting logic here, with the help of ROW_NUMBER
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Project, Type ORDER BY Time) rn
FROM yourTable
)
SELECT
Project,
MAX(CASE WHEN Type = 'Start' THEN Time END) AS Start,
MAX(CASE WHEN Type = 'End' THEN Time END) AS [End]
FROM cte
GROUP BY
Project,
rn
ORDER BY
Project,
rn;
Upvotes: 2