Reputation: 164
I have a table as below
timestamp v1 v2 v3
2020/01/01 08:10:20.300 10 20 30
2020/01/01 08:10:20.306 11 21 31
2020/01/01 08:10:20.310 12 22 32
2020/01/01 08:10:20.318 13 23 33
2020/01/01 08:10:20.325 14 24 34
.......................
2020/01/01 08:10:21.100 19 29 39
As can be seen that the timestamp does not change uniformly in the millisecond and has a lot of granular data. I am interested to condense the table such that, the timestamp and data columns average out for every 100 millisecond ie all the data between 100 millisecond gets averaged out.
I have a solution that seems to be working but the average is over every second and not after every 100 millisecond.
SELECT date_trunc('second', timestamp) AS timestamp
,avg(v1) AS avg_v1
,avg(v2) AS avg_v2
,avg(v3) AS avg_v3
FROM myTable
GROUP BY 1;
Please direct me how to solve this issue. Thank you
Upvotes: 1
Views: 396
Reputation: 222582
Consider casting the timestamp
column to timestamp(1)
: this will actually round it to the closest decimal second.
SELECT
"timestamp"::timestamp(1) AS timestamp,
avg(v1) AS avg_v1,
avg(v2) AS avg_v2,
avg(v3) AS avg_v3
FROM myTable
GROUP BY 1;
Note that this rounds the timestamp instead of truncating it. Typically, 08:10:20.306
would become 08:10:20.3
, while 08:10:20.350
would be turned to 08:10:20.4
. This might, or might not be what you really want.
If you really want to truncate to 10s of seconds, then it is a bit more complicated. One option is to truncate the timestamp to minutes, then extract the second parts (all decimals included), turn it to a number, truncate it to 1 decimal, then add it back:
SELECT
date_trunc('minute', "timestamp")
+ interval '1 second'
* trunc((extract(seconds from "timestamp"))::numeric, 1) AS timestamp,
avg(v1) AS avg_v1,
avg(v2) AS avg_v2,
avg(v3) AS avg_v3
FROM myTable
GROUP BY 1;
Another option to truncate, as commented by Gordon Linoff, is to offset then round. This is simpler than the above solution, and probably more efficient:
SELECT
("timestamp" - interval '50 millisecond')::timestamp(1) AS timestamp,
avg(v1) AS avg_v1,
avg(v2) AS avg_v2,
avg(v3) AS avg_v3
FROM myTable
GROUP BY 1;
Upvotes: 1