PostgreSQL агрегирует с несколькими параметрами - PullRequest
6 голосов
/ 16 декабря 2011

Я пытался обернуться вокруг создания агрегатов в PostgreSQL (8.4 или 9.1), которые принимают один или несколько параметров.

В качестве примера можно было бы создать расширение PL/R для вычисленияр-й квантиль, с 0 <= p <= 1.Это выглядело бы примерно как quantile(x,p) и как часть запроса:

select category,quantile(x,0.25)
from TABLE
group by category
order by category;

Где TABLE (category:text, x:float).

Предложения?

Ответы [ 2 ]

5 голосов
/ 16 декабря 2011

Надеюсь, этот пример поможет.Вам нужна функция, которая принимает (аккумулятор, агрегатные аргументы) и возвращает новое значение аккумулятора.Поиграйте с приведенным ниже кодом, и вы должны почувствовать, как все это сочетается.

BEGIN;

CREATE FUNCTION sum_product_fn(int,int,int) RETURNS int AS $$
    SELECT $1 + ($2 * $3);
$$ LANGUAGE SQL;           

CREATE AGGREGATE sum_product(int, int) (
    sfunc = sum_product_fn,
    stype = int, 
    initcond = 0
);

SELECT 
    sum(i) AS one,     
    sum_product(i, 2) AS double,
    sum_product(i,3) AS triple
FROM generate_series(1,3) i;

ROLLBACK;      

Это должно дать вам что-то вроде:

 one | double | triple 
-----+--------+--------
   6 |     12 |     18
3 голосов
/ 09 января 2012

Этого можно добиться с помощью функции управления окнами ntile

-- To calculate flexible quantile ranges in postgresql, for example to calculate n equal 
-- frequency buckets for your data for use in a visualisation (such as binning for a 
-- choropleth map), you can use the following SQL:

-- this functions returns 6 equal frequency bucket ranges for my_column.
SELECT ntile, avg(my_column) AS avgAmount, max(my_column) AS maxAmount, min(my_column) AS     minAmount 
FROM (SELECT my_column, ntile(6) OVER (ORDER BY my_column) AS ntile FROM my_table) x
GROUP BY ntile ORDER BY ntile

Подробнее о функции управления окнами ntile () и * * можно узнать по адресу http://database -programmer.blogspot.com / 2010/11/really-cool-ntile-window-function.html

...