PostgreSQL:按日期分组,也包括前几天的结果

时间:2011-11-11 02:26:51

标签: sql postgresql

很抱歉,如果这成为双重帖子。

我正在编写一个查询,用于确定按特定基金持有股份的客户数量,该基金按该基金每天发生的交易分组。

所以我的交易表是:

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 个答案:

答案 0 :(得分:2)

您需要的是窗口函数,特别是使用“滞后”功能。我不确定你拥有什么版本的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;

这样的效果。希望这有助于:)。