I need to extract data from a postgres table, where I want to look at nearby records within a 30 seconds of timesstamp with two columns match and fetch the value which is having max value.
id | datetime | col_1 | col_2|dist| dir
-------+---------------------+-------+------+----+------
103 | 2023-10-06 20:12:19 | 135 | 13 | 57 | EAST
213 | 2023-10-06 20:32:34 | 135 | 13 | 54 | NORTH
103 | 2023-10-06 20:00:19 | 135 | 13 | 70 | EAST
103 | 2023-10-06 20:42:34 | 135 | 13 | 54 | NORTH
213 | 2023-10-06 20:12:19 | 135 | 13 | 57 | NORTH
222 | 2023-10-06 18:42:34 | 135 | 13 | 45 | EAST
222 | 2023-10-06 20:42:34 | 135 | 13 | 54 | EAST
First, 'id'
and 'dir'
column should be same then need to check the 'datetime'
values with in 30 mins range and get all column values where 'dist'
column value is max.
Output –
id | datetime | col_1 | col_2|dist| dir
-------+---------------------+-------+------+----+------
103 | 2023-10-06 20:00:19 | 135 | 13 | 70 | EAST
213 | 2023-10-06 20:12:19 | 135 | 13 | 57 | NORTH
103 | 2023-10-06 20:42:34 | 135 | 13 | 54 | NORTH
222 | 2023-10-06 18:42:34 | 135 | 13 | 45 | EAST
222 | 2023-10-06 20:42:34 | 135 | 13 | 54 | EAST
I am trying below query but didn’t work-
WITH cte AS ( SELECT id, datetime, col_1, col_2, dist, dir
FROM table_1)
SELECT table_1.*
FROM table_1
JOIN cte ON table_1.id = cte.id AND table_1.dir = cte.dir
AND table_1.datetime BETWEEN cte.datetime - INTERVAL '30 MINUTE'
AND cte.datetime + INTERVAL '30 MINUTE'
ORDER BY id;
create DB queries –
CREATE TABLE table_1
(
id character varying NOT NULL, PRIMARY KEY(datetime, id),
datetime timestamp without time zone NOT NULL,
col_1 int,
col_2 int,
dist int,
dir character varying(5)
);
INSERT INTO
table_1(id, datetime, col_1, col_2, dist, dir)
VALUES
('103', '2023-10-06 20:12:19', 135, 130, 57, 'EAST'),
('213', '2023-10-06 20:32:34', 135, 130, 54, 'NORTH'),
('103', '2023-10-06 20:00:19', 135, 130, 70, 'EAST'),
('103', '2023-10-06 20:42:34', 135, 130, 54, 'NORTH'),
('213', '2023-10-06 20:12:19', 135, 130, 57, 'NORTH'),
('222', '2023-10-06 18:42:34', 135, 130, 45, 'EAST'),
('222', '2023-10-06 20:42:34', 135, 130, 54, 'EAST');
2
Answers
The following query returns the described result set:
The query partitions the data by
id
anddir
and determines the maximumdist
within a +/- 30 minute range of each data point and then filters for only those rows wheredist
is equal to the corresponding maximum.For PostgreSql 10 and earlier, you may use
self join
instead window function with time interval.For partition
use JOIN condition
See example
Fiddle
Before filter we have