PostgreSQL: группировка по дате и включая результаты предыдущих дней - PullRequest
1 голос
/ 11 ноября 2011

Извините, если это стало двойной записью.

Я пишу запрос, который определяет количество клиентов, владеющих акциями в определенном фонде, сгруппированном по дням, когда транзакции происходили с этим фондом.

Итак, моя таблица транзакций:

CREATE TABLE trans(
transID SERIAL PRIMARY KEY,
sin CHAR(9) REFERENCES customer(sin) ON UPDATE CASCADE ON DELETE CASCADE,
fundID INT REFERENCES fund(fundID) NOT NULL,
transDate DATE,
shares INT,
FOREIGN KEY (fundID) REFERENCES fund(fundID) ON UPDATE CASCADE ON DELETE CASCADE
);

Вот мой запрос:

   select f.transdate, count (f.sin) 
   from (select t1.transdate, t1.sin, sum(t2.shares) 
          from fund f natural join trans t1 natural join trans t2 
          where f.fundname='Energy' 
          and t1.sin = t2.sin 
          and t2.transdate <= t1.transdate 
          group by t1.transdate, t1.sin 
          having sum(t2.shares) > 0)as f group by f.transdate 
          order by f.transdate;

Возвращает общее количество клиентов, владеющих акциями в этот день.Однако я также хочу добавить клиентов, которые держали акции в одном и том же фонде все дни раньше.

Итак, допустим, если я добавлю следующие вставки:

INSERT INTO trans VALUES (DEFAULT, '1', '3', '2011-10-10', 400);
INSERT INTO trans VALUES (DEFAULT, '3', '3', '2011-10-11', 324);
INSERT INTO trans VALUES (DEFAULT, '5', '3', '2011-10-17', 201);
INSERT INTO trans VALUES (DEFAULT, '8', '3', '2011-10-17', 472);

Итак, запрос, который я сформулировал, вернет это:

 transdate  | count 
------------+-------
 2011-10-10 |     1
 2011-10-11 |     1
 2011-10-17 |     2

Однако мне бы хотелосьчтобы быть таким:

 transdate  | count 
------------+-------
 2011-10-10 |     1
 2011-10-11 |     2
 2011-10-17 |     4

Как вы можете видеть, в конце 2011-10-11 года в этом фонде находилось 2 человека и т. д.

Любая помощь?

1 Ответ

2 голосов
/ 11 ноября 2011

То, что вам нужно, это функция управления окнами, в частности, с использованием функции «задержки».Я не уверен, какая у вас версия PostgreSQL и когда эти оконные функции были впервые поддержаны, но вот документация для текущей серии 9.x:

Обзор окон: http://www.postgresql.org/docs/9.0/interactive/tutorial-window.html

и:

Оконные функции: http://www.postgresql.org/docs/9.0/interactive/functions-window.html

Возможно, существует довольно эффективный способ переписать ваш запрос с учетом этого, но у меня нет времени работать над этим.Я могу сказать, что самый простой, хотя и не самый лучший метод получения ожидаемого результата - взять текущий запрос, сделать его CTE (http://www.postgresql.org/docs/9.0/interactive/queries-with.html)) и использовать функцию запроса в запросе, использующем CTE.Значение:

WITH cte (transdate, peoplecount) AS (
 your_current_query
)
SELECT transdate, lag() OVER (...)
FROM cte;

Что-то на этот счет. Надеюсь, это поможет:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...