I have a table like the following, each entry a change in STATUS on the given time.
The status can be repeated because other columns have sub-status information.
How can I get a percentage time for each status by, say, hour?
NAME STATUS_CHANGE_TIME STATUS
foo 15-MAY-11 18:52 A
foo 15-MAY-11 18:38 A
foo 15-MAY-11 18:33 B
foo 15-MAY-11 16:53 A
foo 15-MAY-11 16:47 B
foo 15-MAY-11 13:37 A
foo 15-MAY-11 13:33 C
foo 15-MAY-11 10:23 C
foo 15-MAY-11 10:17 A
foo ...
Desired return:
HH24 STATUS PERCENT
10 ...
11 C 100 (No entries; last change was to C)
12 C 100 "" ""
13 C 62
13 A 38 (From C to A at :37 with 23 mins left; 23/60 ~ 38%)
14 A 100
15 A 100
16 A 90 (= A for first 47 minutes, then for another 7)
16 B 10 (16:53 - 16:47 = 6 minutes or 10% of an hour)
17 A 100
18 ... etc.
Great question, this was an interesting challenge!
What you need is an ancillary table to store each time division (in this case, hours), then join to it where the status updates overlap.
LEAD()can grab the next status entry to check when it was, andGREATEST()andLEAST()can figure out which time is applicable for the start/end of the status for each hour.Of course, this is much easier explained in an example. Here is the
HOURStable needed:The following is just population of your test data from your question.
Now here is the select statement to get the required percentages.