I am using postgresql version 10.9 and I am trying to split overlapping intervals from 2 different tables that record events.
For each interval of the main table, I need to detect the person movement (arrival or departure) that overlaps the main interval, and split it for each prod_line by the event. If the person movement is arrival, I need to take the highest value of a 5 minutes interval consecutive arrivals. If the person movement is departure, I need to take the lowest value of a 5 minutes interval of consecutive departures.
I only found samples of merging overlapping intervals for date ranges within the same table.
I tried to write a function that loops through the main data set and for each interval to loop through the attendance intervals and return overlapping intervals.
I failed to make the attendance intervals take into account the highest arrival_time within a 5 minute interval and the lowest value within a 5 minute interval for departure time and also further compare it to the main current interval to properly split it as expected.
My 2 tables have the following structure
main (prod_line text, item_code text, start_time timestamp without time zone, end_time timestamp without time zone);
attendance(person_id text, prod_line text, arrival_time timestamp without time zone, departure_time timestamp without time zone);
having the following sample data for Main:
"RS-5";"110067805";"2019-06-11 06:30:41";"2019-06-11 15:00:05"
and for Attendance
11770;"RS-5";"2019-06-11 06:30:09";"2019-06-11 11:00:12"
675;"RS-5";"2019-06-11 06:30:14";"2019-06-11 10:00:01"
11504;"RS-5";"2019-06-11 06:30:17";"2019-06-11 10:00:07"
101;"RS-5";"2019-06-11 06:30:23";"2019-06-11 11:00:10"
627;"RS-5";"2019-06-11 06:30:25";"2019-06-11 11:00:20"
11765;"RS-5";"2019-06-11 06:34:29";"2019-06-11 11:00:01"
675;"RS-5";"2019-06-11 11:30:09";"2019-06-11 15:00:25"
627;"RS-5";"2019-06-11 11:30:16";"2019-06-11 15:00:24"
11504;"RS-5";"2019-06-11 11:30:19";"2019-06-11 15:00:18"
11770;"RS-5";"2019-06-11 11:30:22";"2019-06-11 15:00:15"
11765;"RS-5";"2019-06-11 11:30:25";"2019-06-11 15:00:12"
101;"RS-5";"2019-06-11 11:30:27";"2019-06-11 15:00:30"
353;"RS-5";"2019-06-11 15:01:39";"2019-06-11 15:10:35"
11712;"RS-5";"2019-06-11 15:01:42";"2019-06-11 15:10:34"
817;"RS-5";"2019-06-11 15:01:44";"2019-06-11 15:10:32"
1337;"RS-5";"2019-06-11 15:01:46";"2019-06-11 15:10:30"
1363;"RS-5";"2019-06-11 15:01:48";"2019-06-11 15:10:28"
1510;"RS-5";"2019-06-11 15:01:50";"2019-06-11 15:10:24"
Rextester Fiddle
Basically, I would like to get a result of the intervals looking like this:
result (prod_line text, item_code text, start_time timestamp without time zone, end_time timestamp without time zone);
with the values
"RS-5";"110067805";"2019-06-11 06:34:29";"2019-06-11 10:00:01"
"RS-5";"110067805";"2019-06-11 10:00:07";"2019-06-11 11:00:01"
"RS-5";"110067805";"2019-06-11 11:00:01";"2019-06-11 11:30:27"
"RS-5";"110067805";"2019-06-11 11:30:27";"2019-06-11 15:00:05"
In case anyone else needs a solution for this, I figured something out (maybe not the best but it works)
The solution is available here
Related
I'm trying to do an alert of sorts for customers joining. The alert needs to run on an interval of one hour, which is possible with an integration we have.
The sample data is this:
Name
Time
John
2022-04-21T13:49:51
Mary
2022-04-23T13:49:51
Dave
2022-04-25T13:49:51
Gregg
2022-04-27T13:49:51
so the problem with the below output is this only captures the "count" within the hour. And will yield no results. But I'm trying to determine the moment (well, within the hour) the threshold crosses above a count of 3. Is there something I'm missing?
SELECT COUNT (name)
FROM Table
WHERE Time >= TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL -60 MINUTE)
HAVING COUNT (NAME) > 3
I have a table in a dataset with the following schema:
date TIMESTAMP
id INTEGER
...
The table is partitioned on the date column.
Displaying a preview of the table in the BQ UI reveals it has many rows in February:
date, id, ...
2019-02-19 16:18:00 UTC, 534480012, ...
2019-02-19 16:23:00 UTC, 534423879, ...
However, this query returns zero results:
SELECT id FROM `<project>.<dataset>.<table>`
WHERE
TIMESTAMP_SUB(date, INTERVAL 60*24 HOUR) <= `date` AND
TIMESTAMP_SUB(date, INTERVAL 24 HOUR) >= `date`
(And yes, as of this writing, February rows should show up.)
What's more is even the "default" query returns zero results:
SELECT id FROM `<project>.<dataset>.<table>` WHERE date = TIMESTAMP("2019-02-19") LIMIT 1000
No errors in either case. Just empty results. What am I doing wrong?
How can this ever be true?
TIMESTAMP_SUB(date, INTERVAL 24 HOUR) >= `date`
If you subtract 24 hours, then it will be less then date rather than bigger than date.
As for your second query, you simply have no timestamps that are exactly at midnight. Presumably, you intend something like:
WHERE DATE(date) = DATE('2019-02-19')
I strongly recommend that you change the name of the column. Naming a column after a SQL keyword is a bad idea. Calling something a "date" when it is really a timestamp is misleading and confusing.
How to find difference in seconds betweem chosen moment and values from table using PostgreSQL?
For example chosen moment is '2003-05-21' and table look like
TABLE
Name Date_of_Birth
Charles 2007-12-12
Matti 2003-09-20
Kath 2009-11-09
I tried to use this
SELECT EXTRACT(SECONDS FROM TIMESTAMP '2013-05-21')-EXTRACT(SECONDS FROM TIMESTAMP (SELECT Date_of_Birth FROM TABLE);
How to find how many second has gone from date of birth to the moment for every person from table? And results should be represented as table
Forgive me if my question is not understantable?
Just extract the epoch from the difference:
select extract(epoch from timestamp '2013-05-21' - date_of_birth)
from the_table;
From the manual
epoch
[...] for interval values, the total number of seconds in the interval
I have a table with time series column in the millisecond, I want to resample the time series and apply mean on the group. How can I implement it in Postgres?
"Resample" means aggregate all time stamps within one second or one minute. All rows within one second or one minute form a group.
table structure
date x y z
Use date_trunc() to truncate timestamps to a given unit of time, and GROUP BY that expression:
SELECT date_trunc('minute', date) AS date_truncated_to_minute
, avg(x) AS avg_x
, avg(y) AS avg_y
, avg(z) AS avg_z
FROM tbl
GROUP BY 1;
Assuming your misleadingly named date column is actually of type timestamp or timestamptz.
Related answer with more details and links:
PostgreSQL: running count of rows for a query 'by minute'
I have a table that stores historical data. I get a row inserted in this query every 30 seconds from different type of sources and obviously there is a time stamp associated.
Let's make my parameter as disservice to 1 hour.
Since I charge my services based on time, I need to know, for example, in a specific month, if there is a period within this month in which the there is an interval which is equal or exceeds my 1 hour interval.
A simplified structure of the table would be like:
tid serial primary key,
tunitd id int,
tts timestamp default now(),
tdescr text
I don't want to write a function that loops through all the records comparing them one by one as I suppose it is time and memory consuming.
Is there any way to do this directly from SQL maybe using the interval type in PostgreSQL?
Thanks.
this small SQL query will display all gaps with the duration more than one hour:
select tts, next_tts, next_tts-tts as diff from
(select a.tts, min(b.tts) as next_tts
from test1 a
inner join test1 b ON a.tts < b.tts
GROUP BY a.tts) as c
where next_tts - tts > INTERVAL '1 hour'
order by tts;
SQL Fiddle