3

私は多くの行を持つテーブルを持っているので、このクエリを実行すると:

SELECT     
    date_trunc('hour', fecha) AS momento
    ,(extract(minute FROM fecha)::int / 5) AS min
    ,count(fecha) AS cuenta
FROM   table1
WHERE fk_id_busqueda=$id_busqueda 
GROUP  BY 1, 2
ORDER  BY 1, 2;

時間がかかります。私が考えている解決策の1つは、データを日付順に並べ替えて、前の行のモーメントがループのある実際のモーメントと同じになるたびに1つを合計できるpostgres関数を作成することです。そして、が異なる場合は、値をリセットして次の行に渡します。この関数はid_busqueda(int)を受け取るという考え方です。

出力は次のようになります。

 2013-01-20 00:00:00 |         0 |    16
 2013-01-20 00:00:00 |         1 |    30
 2013-01-20 00:00:00 |         2 |    27
 2013-01-20 00:00:00 |         3 |    30
 2013-01-20 00:00:00 |         4 |    33
 2013-01-20 00:00:00 |         5 |    21
 2013-01-20 00:00:00 |         6 |    27
 2013-01-20 00:00:00 |         7 |    27
 2013-01-20 00:00:00 |         8 |    19
 2013-01-20 00:00:00 |         9 |    13
 2013-01-20 00:00:00 |        10 |    17
 2013-01-20 00:00:00 |        11 |    24
 2013-01-20 01:00:00 |         0 |    12
 2013-01-20 01:00:00 |         1 |    15
 2013-01-20 01:00:00 |         2 |    25
 2013-01-20 01:00:00 |         3 |    19
 2013-01-20 01:00:00 |         4 |    10
 2013-01-20 01:00:00 |         5 |    12
 2013-01-20 01:00:00 |         6 |    13
4

2 に答える 2

2

fk_id_busqueda列でのインデックスの作成に加えて、これは実行時間からもう少し短縮する必要があります。

SELECT     
    date_trunc('minute', fecha) - 
    (extract(minute from fecha)::integer % 5) * interval '1 minute' as momento
    ,count(fecha) AS cuenta
FROM   table1
WHERE fk_id_busqueda=$id_busqueda 
GROUP  BY 1
ORDER  BY 1
于 2013-01-31T21:31:12.303 に答える
1

この関数がその役割を果たしてくれることを願っています。

create or replace function myfunc(id_busqueda integer)
returns table (momento timestamp, min int, cuenta int)
language plpgsql as $$
declare
    t record;
    momento timestamp;
    imomento timestamp;
    mins integer;
    imins integer;
    was boolean;
begin
    was := false;
    cuenta := 1;
    for t in 
        select fecha 
        from table1 
        where fk_id_busqueda = id_busqueda
        order by fecha
    loop
        momento := date_trunc('hour', t.fecha);
        mins := extract(minute FROM t.fecha)::int / 5;
        if imins = mins and imomento = momento then
            cuenta := cuenta+ 1;
        else
            if was then
                return query select imomento, imins, cuenta;
            end if;
            cuenta := 1;
            imins := mins;
            imomento := momento;
            was := true;
        end if;
    end loop;
    if was then
        return query select imomento, imins, cuenta;
    end if;
end; $$;
于 2013-01-31T21:19:57.110 に答える