interpolated_duration_in()

Calculate the total duration in a given state from a state aggregate. Unlike duration_in, you can use this function across multiple state aggregates that cover different time buckets. Any missing values at the time bucket boundaries are interpolated from adjacent StateAggs/TimelineAggs.

  1. interpolated_duration_in(
  2. state [TEXT | BIGINT],
  3. tws [StateAgg | TimelineAgg],
  4. start TIMESTAMPTZ,
  5. interval INTERVAL,
  6. prev [StateAgg | TimelineAgg],
  7. next [StateAgg | TimelineAgg]
  8. ) RETURNS DOUBLE PRECISION
warning

Experimental features could have bugs. They might not be backwards compatible, and could be removed in future releases. Use these features at your own risk, and do not use any experimental features in production.

Required arguments

NameTypeDescription
stateTEXT or BIGINTState to query
aggregateStateAgg or TimelineAggPreviously created state_agg aggregate
startTIMESTAMPTZThe start of the interval which this function should cover (if there is a preceeding point)
intervalINTERVALThe length of the interval

Optional arguments

NameTypeDescription
prevStateAgg or TimelineAggThe StateAgg or TimelineAgg from the prior interval, used to interpolate the value at start. If NULL, the first timestamp in aggregate is used as the start of the interval.
nextStateAgg or TimelineAggThe StateAgg or TimelineAgg from the following interval, used to interpolate the value at start + interval. If NULL, the last timestamp in aggregate is used as the end of the interval.

Returns

ColumnTypeDescription
interpolated_duration_inINTERVALThe total time spent in the target state. Displayed as days, hh:mm:ss, or a combination of the two.

Sample usage

This example creates a simple test table:

  1. SET timezone TO 'UTC';
  2. CREATE TABLE states(time TIMESTAMPTZ, state TEXT);
  3. INSERT INTO states VALUES
  4. ('1-1-2020 10:00', 'starting'),
  5. ('1-1-2020 10:30', 'running'),
  6. ('1-2-2020 16:00', 'error'),
  7. ('1-3-2020 18:30', 'starting'),
  8. ('1-3-2020 19:30', 'running'),
  9. ('1-4-2020 12:00', 'stopping');

You can query this table for the time spent in the running state, like this:

  1. SELECT
  2. time,
  3. toolkit_experimental.interpolated_duration_in(
  4. 'running',
  5. agg,
  6. time,
  7. '1 day',
  8. LAG(agg) OVER (ORDER BY time),
  9. LEAD(agg) OVER (ORDER BY time)
  10. ) FROM (
  11. SELECT
  12. time_bucket('1 day', time) as time,
  13. toolkit_experimental.state_agg(time, state) as agg
  14. FROM
  15. states
  16. GROUP BY time_bucket('1 day', time)
  17. ) s;

Which gives the result:

  1. time | interpolated_duration_in
  2. ------------------------+--------------------------
  3. 2020-01-01 00:00:00+00 | 13:30:00
  4. 2020-01-02 00:00:00+00 | 16:00:00
  5. 2020-01-03 00:00:00+00 | 04:30:00
  6. 2020-01-04 00:00:00+00 | 12:00:00

If you prefer to see the result in seconds, EXTRACT the epoch from the returned result.