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