Error 500
Error 500

Reputation: 43

Combine 2 rows into 1 row (Start and End times)

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

Answers (2)

GMB
GMB

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

Demo on DB Fiddle:

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

Tim Biegeleisen
Tim Biegeleisen

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;

screen capture of demo below

Demo

Upvotes: 2

Related Questions