I have a logging table that contains data that looks like this:
ID MSG DATE --------------------------------------------- 1 TEst 2010-01-01 09:00:00 2 Job Start 2010-01-01 09:03:00 3 Do something 2010-01-01 09:03:10 4 Do something else 2010-01-01 09:03:12 5 Do something 2010-01-01 09:04:19 6 Job End 2010-01-01 09:06:30 7 Job Start 2010-01-01 09:18:03 8 Do something 2010-01-01 09:18:17 9 Do other thing 2010-01-01 09:19:48 10 Job End 2010-01-01 09:20:27
It contains (among other things) messags written by the application. I am interested in producing a report of everything that gets written between a "Job Start" record and a "Job End" record, for all such pairs of "Job Start" and "Job End". Ideally the report would look like this:
BATCH_NUM ID MSG DATE --------------------------------------------------------- 1 3 Do something 2010-01-01 09:03:10 1 4 Do something else 2010-01-01 09:03:12 1 5 Do something 2010-01-01 09:04:19 2 8 Do something 2010-01-01 09:18:17 2 9 Do other thing 2010-01-01 09:19:48
(line break between batches added to make it easier to read)
The output report omits the "Job STart and "Job End" messages, as well as the "TEst" message (which exists outside a pair of "Job Start" and "Job End".
I'm not even sure where to begin writing this kind of query, or if it's better to go with PL/SQL for this. Heck, I'm not even sure if there's a proper technical term for what I'm trying to do. ;)
(oracle version is 10g)
I'm sure there's a more analytic-ish way to do this, but I'm cheating with scalar subqueries to build the windows.
Here's a way of doing the same trick without using window functions, just in case.
The following sample uses much the same idea as Adam Musch's answer, but gets the logging sets' start and end in a single select which is joined to the logging statement, rather than using scalar sub-queries.
I don't think DENSE_RANK() can be used any more directly because there is no column available to partition on.
Also, either of these solutions assume that the will never be overlapping sets of logs. If a second set starts before the first one ends, it's a whole new problem...