I would like to store date/time ranges in PostgreSQL of some arbitrary events that have a state of open or closed and a date/time of when the state changed.
Events coming from an API will have the following data for a single event:
Request 1:
{
id: 1,
state: 'open',
date: '2020-02-17T10:00:00Z'
}
Request 2:
{
id: 1,
state: 'close',
date: '2020-02-17T10:10:00Z'
}
Request 3:
{
id: 1,
state: 'open',
date: '2020-02-17T11:00:00Z'
}
The requests can come in any order, so future dates can come before past dates or states are not always open -> close -> open -> close. For example the API could send the open states for the same event one after the other.
I was thinking of using the tstzrange
for saving this data in the database in the following form:
CREATE TABLE events (
id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
event_id int,
validity tstzrange
);
The open states are captured in the validity column and close states are the gaps between the validity columns. For example if a single event has the following states and date/times (using only times for simplicity) in this order:
state date/time
close 20:30
open 18:00
close 16:00
open 15:00
open 20:00
close 19:30
The validity rows should look like:
id event_id validity
1 1 [15:00, 16:00)
2 1 [18:00, 19:30)
3 1 [20:00, 20:30)
Event 1
has the state open
between 15:00 - 16:00
, state close
between 16:00 - 18:00
, state open
between 18:00 - 19:30
and so on.
To illustrate this visually:
My problem is that the events are not coming in order, so I don't know how to manipulate the individual validity columns to insert / update these rows.