Oscar
Oscar

Reputation: 744

Group rows if certain column value directly after another in SQL

I'm using MS SQL Server 2008, and I would like this:

+------+--------+--------+------------+
| id   | Name   | Event  | Timestamp  |
+------+--------+--------+------------+
|    0 | bob    | note   | 14:20      |
|    1 | bob    | time   | 14:22      |
|    2 | bob    | time   | 14:40      |
|    3 | bob    | time   | 14:45      |
|    4 | bob    | send   | 14:48      |
|    5 | bob    | time   | 15:30      |
|    6 | bob    | note   | 15:35      |
|    7 | bob    | note   | 18:00      |
+------+--------+--------+------------+

To become this:

+------+--------+--------+------------+
| id   | Name   | Event  | Timestamp  |
+------+--------+--------+------------+
|    0 | bob    | note   | 14:20      |
|    1 | bob    | time   | 14:22      |
|    4 | bob    | send   | 14:48      |
|    5 | bob    | time   | 15:30      |
|    6 | bob    | note   | 15:35      |
+------+--------+--------+------------+

I.e., rows are "grouped" by the "event" column. Only one of each grouped identical "event" is to be shown.

Those two are the only rules.

Upvotes: 3

Views: 2067

Answers (1)

Michał Powaga
Michał Powaga

Reputation: 23183

If ids are one after one try do it this way:

select * into #tab from(
    select 0 as id, 'bob' as name, 'note' as event, '14:20' as time union
    select 1, 'bob', 'time', '14:22' union
    select 2, 'bob', 'time', '14:40' union
    select 3, 'bob', 'time', '14:45' union
    select 4, 'bob', 'send', '14:48' union
    select 5, 'bob', 'time', '15:30' union
    select 6, 'bob', 'note', '15:35' union
    select 7, 'bob', 'note', '18:00'
) t

select t.*
from #tab t
left join #tab t1 on t.id = t1.id + 1 and t1.event = t.event 
    -- and t1.name = t.name -- if there are more names you are going to need this one as well
where t1.id is null

result:

id  name    event   time
0   bob     note    14:20
1   bob     time    14:22
4   bob     send    14:48
5   bob     time    15:30
6   bob     note    15:35

Added:

If ids aren't one after one, you can make them to be:

select identity(int, 1, 1) as id, name, event, time 
into #tab_ordered_ids
from #tab order by name, id, time

Upvotes: 4

Related Questions