Ariod
Ariod

Reputation: 5851

Oracle - help making a query

I have source of data in the following format:

Event Type| Date
1         | 2011-07-14 09:00
1         | 2011-07-14 09:01
1         | 2011-07-14 09:02
2         | 2011-07-14 09:30
2         | 2011-07-14 09:31
1         | 2011-07-14 10:00
1         | 2011-07-14 10:01

Event types are sorted by date, as they occurred. I need to make a query which will show the date ranges when events were used, sorted by date. Like this:

Event Type | Date Range
1          | 2011-07-14 09:00 - 2011-07-14 09:02
2          | 2011-07-14 09:30 - 2011-07-14 09:31
1          | 2011-07-14 10:00 - 2011-07-14 10:01

Do you have any hints? I reckon this will probably need to be done with analytic functions, but I haven't been able to come up with a decent solution yet.

Upvotes: 1

Views: 57

Answers (2)

Andriy M
Andriy M

Reputation: 77657

You could also try the following approach:

WITH ranked AS (
  SELECT
    EventType,
    Date,
    ROW_NUMBER() OVER (ORDER BY Date) -
      ROW_NUMBER() OVER (PARTITION BY EventType ORDER BY Date) AS GroupID
  FROM Events
)
SELECT
  EventType,
  MIN(Date) AS StartDate,
  MAX(Date) AS EndDate
FROM ranked
GROUP BY
  GroupID,
  EventType
ORDER BY
  MIN(Date)

Upvotes: 2

MatBailie
MatBailie

Reputation: 86706

I'm sure there is a better solution, but what about this?

WITH
  ordered_data AS
(
  SELECT ROW_NUMBER() OVER (ORDER BY Date) AS row_id, * FROM event_data
),
  [start_events] AS
(
  SELECT * FROM ordered_data  AS [start]
  WHERE NOT EXISTS (SELECT * FROM ordered_data WHERE row_id = [start].row_id - 1 AND event_type = [start].event_type)
),
  [end_events] AS
(
  SELECT * FROM ordered_data  AS [end]
  WHERE NOT EXISTS (SELECT * FROM ordered_data WHERE row_id = [end].row_id + 1 AND event_type = [end].event_type)
)

SELECT
  *
FROM
  [start_events]
INNER JOIN
  [end_events]
    ON [end_events].row_id = (SELECT MIN(row_id) FROM [end_events] WHERE row_id >= [start_events].row_id)

This should also cope with scenarios where the 'group' only has one event in it; Such as (1, 1, 2, 1, 1)

Upvotes: 1

Related Questions