Function Postgresql循环函数

Function Postgresql循环函数,function,postgresql,date,loops,aggregate-functions,Function,Postgresql,Date,Loops,Aggregate Functions,我有一个包含许多行的表,因此当我进行此查询时: 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; 这需要很多时间。我正在考虑的

我有一个包含许多行的表,因此当我进行此查询时:

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;
这需要很多时间。我正在考虑的一个解决方案是创建一个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

我希望这个功能可以完成这项任务

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; $$;

除了在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

这个表中大约有多少条记录?您在
fk\u id\u busqueda
列上有索引吗?