Применение оконных функций
Как мне не хватало нестрогого выполнения group by. Однако на просторах интернета удалось найти обход. Обход заключается в использовании оконных функций.
Оконная функция - функция агрегирования (sum, min, max …), которая выполняется для части множества.
Задача
Требуется вывести id свойства, определить действует оно или нет и iddoc документа, в котором устанавливалось свойство. Для этого будем использовать оконную функцию over().
Задаем таблицу и заполняем ее данными.
CREATE TABLE test.test_group_by ( iddoc DOUBLE PRECISION , id_svo_vo DOUBLE PRECISION , "date" TIMESTAMP , is_active DOUBLE PRECISION ); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 0, 1,'2012/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 0, 2,'2012/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 0, 3,'2012/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 1, 4,'2012/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 1, 5,'2012/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 2, 1,'2012/01/02 00:00:00.000', 0); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 2, 4,'2012/01/02 00:00:00.000', 0); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 2, 5,'2012/01/02 00:00:00.000', 0); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 3, 1,'2013/01/01 00:00:00.000', 1); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 4, 2,'2014/01/02 00:00:00.000', 0); INSERT INTO test.test_group_by(iddoc, id_svo_vo, "date", is_active) VALUES ( 4, 3,'2014/01/02 00:00:00.000', 0);
Далее выполняем скрипт, который выводит требуемые данные
SELECT *
FROM (
SELECT
iddoc,
id_svo_vo,
max("date") over(partition by id_svo_vo) as max_date,
date,
is_active
FROM test.test_group_by
) as t1
WHERE max_date = date;
Функция агрегирования работает на множестве ключей id_svo_vo. В результате добавляется к каждой строке столбец с максимальной датой на множестве ключей id_svo_vo. В where max_date = date идет отбор необходимых данных, у которых максимальная дата на множестве совпадает с датой самого документа.

Красота да и только!
Ссылки на материалы:
- Оконные функции http://postgresql.ru.net/manual/tutorial-window.html
- Выражения, возвращающие одиночное значение http://postgresql.ru.net/manual/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS
- Подробности
- Опубликовано: 29 Март 2014
- Просмотров: 4944