I have a table like this
x
| winner | year |
|--------|------|
| alice | 1999 |
| bob | 2000 |
| bob | 2001 |
| alice | 2003 |
| alice | 2005 |
| alice | 2007 |
I’d like to infer non-overlapping spells, i.e. a table that looks like.
| winner | start| end |
|--------|------|------|
| alice | 1999 | 1999 |
| bob | 2000 | 2001 |
| alice | 2003 | 2007 |
In python, I would do something like
winners = [(1999, 'alice'),
(2000, 'bob'),
(2001, 'bob'),
(2003, 'alice'),
(2005, 'alice'),
(2007, 'alice')]
winners.sort()
spells = []
spell = {}
for year, name in winners:
if spell:
if name == spell['name']:
spell['end'] = year
else:
spells.append(spell)
spell = {'name': name, 'start': year, 'end': year}
else:
spell = {'name': name, 'start': year, 'end': year}
But am not sure how to achieve the same result in SQL.
Advertisement
Answer
This is a gaps and islands problem. The simplest way is to use row_number()
:
select name, min(year), max(year)
from (select t.*, row_number() over (partition by name order by year) as seqnum
from t
) t
group by name, year - seqnum