Создайте статистическую функцию, которая возвращает значение column1, связанное с максимальным значением column2. - PullRequest
1 голос
/ 06 марта 2019

Мне нужно создать агрегатную функцию.Например, MAX (столбец) возвращает максимальные значения столбца из проанализированных строк.Моя новая функция LAST_ALERT_VALUE (столбец) должна возвращать значение столбца строки, которая имеет наибольшее время приема.

Пример: если у меня есть:

| severity       | reception_time          |
|----------------+-------------------------|
| 1              + 2016-07-04 00:00:00.000 |
| 3              + 2016-09-04 00:00:00.000 |
| 4              + 2016-08-04 00:00:00.000 |
| 2              + 2016-11-04 00:00:00.000 |
| 5              + 2016-10-04 00:00:00.000 |

, тогда LAST_ALERT_VALUE (серьезность) должен вернуть 2

I Вот мой код:

CREATE OR REPLACE FUNCTION max_reception_time(time1 anyelement, time2 anyelement) RETURNS anyelement AS $$
BEGIN
if time1 > time2 then
    return time1;
end if;
return time2;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION last_alert_value_func(p_reception_time anyelement) RETURNS anyelement AS $$
BEGIN
SELECT severity FROM report.report_table AS r WHERE r.reception_time = p_reception_time;
END;
$$ LANGUAGE plpgsql;


CREATE AGGREGATE last_alert_value(anyelement)
(
    sfunc = max_reception_time,
    stype = anyelement,
    finalfunc = last_alert_value_func
);

select last_alert_value(severity) from report.report_table;

У меня ошибка: ОШИБКА: оператор не существует: отметка времени без часового пояса = alertseverityenum

Как я могу сделать last_alert_value(серьезность) работает?Я также хочу дать в качестве аргумента другие столбцы для last_alert_value, как я могу это сделать?

1 Ответ

2 голосов
/ 06 марта 2019

Ваша совокупность бессмысленна, потому что вы можете просто

select severity
from report_table
order by reception_time desc
limit 1;

Если предположить, что это только пример пользовательского агрегата с более чем одним аргументом, решение может выглядеть следующим образом:

create or replace function max_reception_time(state_rec report_table, severity int, reception_time timestamp) 
returns report_table language sql as $$
    select case 
        when state_rec.reception_time > reception_time
        then state_rec
        else (severity, reception_time)::report_table
        end;
$$;

create or replace function max_reception_time_final(state_rec report_table)
returns int language sql as $$
    select state_rec.severity
$$;

create aggregate last_alert_value(severity int, reception_time timestamp)
(
    sfunc = max_reception_time,
    stype = report_table,
    finalfunc = max_reception_time_final
);

select last_alert_value(severity, reception_time)
from report_table t;

Обратите внимание, что я использовал report_table в качестве типа данных состояния. Вместо этого вы можете создать составной тип.

Рабочий код в rextester.

...