Ответ 1
Вы хотите, чтобы агрегированные функции назывались min
и max
. См. Документацию и учебник по PostgreSQL:
- http://www.postgresql.org/docs/current/static/tutorial-agg.html
- http://www.postgresql.org/docs/current/static/functions-aggregate.html
В PostgreSQL нет встроенной медианы, однако она была реализована и внесена в wiki:
http://wiki.postgresql.org/wiki/Aggregate_Median
Он использовался так же, как min
и max
после его загрузки. Будучи написано на PL/PgSQL, это будет немного медленнее, но там есть версия C, которую вы могли бы адаптировать, если бы скорость была жизненно важна.
ОБНОВЛЕНИЕ После комментария:
Похоже, вы хотите показать статистические агрегаты наряду с отдельными результатами. Вы не можете сделать это с помощью простой агрегатной функции, потому что вы не можете ссылаться на столбцы не в GROUP BY
в списке результатов.
Вам нужно будет получить статистику из подзапросов или использовать ваши агрегаты в качестве функций окна.
Данные фиктивных данных:
CREATE TABLE dummystats ( depname text, empno integer, salary integer );
INSERT INTO dummystats(depname,empno,salary) VALUES
('develop',11,5200),
('develop',7,4200),
('personell',2,5555),
('mgmt',1,9999999);
... и после добавления медианного агрегата из вики-страницы PG:
Вы можете сделать это с помощью обычного агрегата:
regress=# SELECT min(salary), max(salary), median(salary) FROM dummystats;
min | max | median
------+---------+----------------------
4200 | 9999999 | 5377.5000000000000000
(1 row)
но не это:
regress=# SELECT depname, empno, min(salary), max(salary), median(salary)
regress-# FROM dummystats;
ERROR: column "dummystats.depname" must appear in the GROUP BY clause or be used in an aggregate function
поскольку в модели агрегации не имеет смысла показывать средние значения вместе с отдельными значениями. Вы можете показывать группы:
regress=# SELECT depname, min(salary), max(salary), median(salary)
regress-# FROM dummystats GROUP BY depname;
depname | min | max | median
-----------+---------+---------+-----------------------
personell | 5555 | 5555 | 5555.0000000000000000
develop | 4200 | 5200 | 4700.0000000000000000
mgmt | 9999999 | 9999999 | 9999999.000000000000
(3 rows)
... но похоже, что вы хотите, чтобы отдельные значения. Для этого вы должны использовать window, новую функцию в PostgreSQL 8.4.
regress=# SELECT depname, empno,
min(salary) OVER (),
max(salary) OVER (),
median(salary) OVER ()
FROM dummystats;
depname | empno | min | max | median
-----------+-------+------+---------+-----------------------
develop | 11 | 4200 | 9999999 | 5377.5000000000000000
develop | 7 | 4200 | 9999999 | 5377.5000000000000000
personell | 2 | 4200 | 9999999 | 5377.5000000000000000
mgmt | 1 | 4200 | 9999999 | 5377.5000000000000000
(4 rows)
См. также: