Sql 它的性能更高?您可以在传感器列中添加索引或使用WITH子句,在其中您可以计算记录计数,您有没有使用WITH子句?我这样做了,它可以工作,但不幸的是它太慢了。你知道如何重写它以使它更高效吗?你可以在传感器列中添加索引或使用WITH子句来计算记录计数,你有没有
Sql 它的性能更高?您可以在传感器列中添加索引或使用WITH子句,在其中您可以计算记录计数,您有没有使用WITH子句?我这样做了,它可以工作,但不幸的是它太慢了。你知道如何重写它以使它更高效吗?你可以在传感器列中添加索引或使用WITH子句来计算记录计数,你有没有,sql,postgresql,Sql,Postgresql,它的性能更高?您可以在传感器列中添加索引或使用WITH子句,在其中您可以计算记录计数,您有没有使用WITH子句?我这样做了,它可以工作,但不幸的是它太慢了。你知道如何重写它以使它更高效吗?你可以在传感器列中添加索引或使用WITH子句来计算记录计数,你有没有使用WITH子句? timestamp | sensor | details ------------------------------------------- 2018-10-10 08:00:00+01 | A
它的性能更高?您可以在传感器列中添加索引或使用WITH子句,在其中您可以计算记录计数,您有没有使用WITH子句?我这样做了,它可以工作,但不幸的是它太慢了。你知道如何重写它以使它更高效吗?你可以在传感器列中添加索引或使用WITH子句来计算记录计数,你有没有使用WITH子句?
timestamp | sensor | details
-------------------------------------------
2018-10-10 08:00:00+01 | A | [{"result": 1.0, "direction": "up"}, {"result": 2.0, "direction": "up"}]
2018-10-10 09:01:00+01 | A | [{"result": 1.0, "direction": "up"}, {"result": 2.0, "direction": "up"}]
2018-10-10 09:01:00+01 | B | [{"result": 3.0, "direction": "up"}, {"result": 4.0, "direction": "down"}]
2018-10-10 09:01:00+01 | B | [{"result": 5.0, "direction": "up"}, {"result": 6.0, "direction": "up"}, {"result": 7.0, "direction": "down"}]
2018-10-10 09:01:00+01 | A | [{"result": 8.0, "direction": "down"}, {"result": 9.0, "direction": "left"}, {"result": 10.0, "direction": "down"}]
SELECT
CASE -- round by every 15 minutes
WHEN extract('minute' from timestamp) < 15 THEN date_trunc('hour', timestamp)
WHEN extract('minute' from timestamp) < 30 THEN date_trunc('hour', timestamp) + '15 minutes'
WHEN extract('minute' from timestamp) < 45 THEN date_trunc('hour', timestamp) + '30 minutes'
ELSE date_trunc('hour', timestamp) + '45 minutes'
END AS timestamp_rounded,
sensor,
SUM((detail_elems ->> 'result')::numeric) FILTER (WHERE detail_elems ->> 'direction' = 'up') AS up_sum,
SUM((detail_elems ->> 'result')::numeric) FILTER (WHERE detail_elems ->> 'direction' = 'down') AS down_sum,
count(sensor) as record_count
FROM
mytable,
jsonb_array_elements(details) detail_elems
GROUP BY
timestamp_rounded,
sensor
ORDER BY
timestamp_rounded ASC,
sensor ASC
;
timestamp_rounded | sensor | up_sum | down_sum | record_count
------------------------------------------------------------------
2018-10-10 08:00:00+01 | A | 3.0 | | 2 -- expected 1
2018-10-10 09:00:00+01 | A | 3.0 | 18.0 | 5 -- expected 2
2018-10-10 09:00:00+01 | B | 14.0 | 11.0 | 5 -- expected 2
WITH tmp AS (
SELECT
*,
CASE -- round by every 15 minutes
WHEN extract('minute' from timestamp) < 15 THEN date_trunc('hour', timestamp)
WHEN extract('minute' from timestamp) < 30 THEN date_trunc('hour', timestamp) + '15 minutes'
WHEN extract('minute' from timestamp) < 45 THEN date_trunc('hour', timestamp) + '30 minutes'
ELSE date_trunc('hour', timestamp) + '45 minutes'
END AS timestamp_rounded
FROM
mytable
)
SELECT
timestamp_rounded,
sensor,
SUM((detail_elems ->> 'result')::numeric) FILTER (WHERE detail_elems ->> 'direction' = 'up') AS up_sum,
SUM((detail_elems ->> 'result')::numeric) FILTER (WHERE detail_elems ->> 'direction' = 'down') AS down_sum,
(SELECT count(*) from tmp tmp2 where tmp2.timestamp_rounded=tmp.timestamp_rounded and tmp2.sensor=tmp.sensor) as record_count_correct
-- COUNT(*) OVER (PARTITION BY sensor, extract(year from timestamp_rounded), extract(month from timestamp_rounded), extract(day from timestamp_rounded), extract(hour from timestamp_rounded), extract(minute from timestamp_rounded)) AS record_count_incorrect
FROM
tmp,
jsonb_array_elements(details) detail_elems
GROUP BY
timestamp_rounded,
sensor
ORDER BY
timestamp_rounded ASC,
sensor ASC
SELECT
sensor,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'up') AS up_sum,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'down') AS down_sum,
cnt
FROM (
SELECT
*,
COUNT(*) OVER (PARTITION BY sensor) AS cnt
FROM
mytable
)s,
jsonb_array_elements(details) elems
GROUP BY sensor, cnt
SELECT
sensor,
to_timestamp(time_slot * 60 * 15) as time_slot,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'up') AS up_sum,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'down') AS down_sum,
cnt
FROM (
SELECT
*,
EXTRACT(epoch from "timestamp")::int / 60 / 15 as time_slot,
COUNT(*) OVER (PARTITION BY EXTRACT(epoch from "timestamp")::int / 60 / 15, sensor) AS cnt
FROM
mytable
)s,
jsonb_array_elements(details) elems
GROUP BY sensor, time_slot, cnt
FROM
mytable,
jsonb_array_elements(details) elems
SELECT
sensor,
elems.*
FROM
mytable,
jsonb_array_elements(details) elems; --5 and 5 by sensor
"A";"{"result": 1.0, "direction": "up"}"
"A";"{"result": 2.0, "direction": "up"}"
"B";"{"result": 3.0, "direction": "up"}"
"B";"{"result": 4.0, "direction": "down"}"
"B";"{"result": 5.0, "direction": "up"}"
"B";"{"result": 6.0, "direction": "up"}"
"B";"{"result": 7.0, "direction": "down"}"
"A";"{"result": 8.0, "direction": "down"}"
"A";"{"result": 9.0, "direction": "left"}"
"A";"{"result": 10.0, "direction": "down"}"
SELECT
sensor,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'up') AS up_sum,
SUM((elems ->> 'result')::numeric)
FILTER (WHERE elems ->> 'direction' = 'down') AS down_sum,
(select count (*) from mytable i_myt where i_myt.sensor=mytable.sensor )
as record_count --subquery to count
FROM
mytable,
jsonb_array_elements(details) elems
GROUP BY sensor;
"B";14.0;11.0;2
"A";3.0;18.0;2