I'm trying to understand PostgreSQL (9.3) window functions a little bit better. Assume I have a simple table as:
SimpleTable
id int,
tservice timestamp
and wish to:
Select id, tservice , count(*) OVER (PARTITION BY id ....) as counter
from SimpleTable
where the records in SimpleTable have tservice times going back 40 years, but the count needs to be limited to only the three years before each record's tservice timestamp.
How can I produce a count for each record in SimpleTable?
Corollary question: How would the same query be changed to add a count of all records that have occurred three years prior to today's date?
Edit #1: Now I see where this question is to vague (I learned something :)). Using the below answer, I would like to get the 3yrs count and the count from the current date, something like:
3yrs prior current date
1, 100, '2001-01-01 00:00:00', 0 0
2, 100, '2002-01-01 00:00:00', 1 0
3, 100, '2003-01-01 00:00:00', 2 0
4, 100, '2004-01-01 00:00:00', 3 0
5, 100, '2005-01-01 00:00:00', 3 0
6, 100, '2006-01-01 00:00:00', 3 0
7, 100, '2007-01-01 00:00:00', 3 0
8, 100, '2008-01-01 00:00:00', 3 0
9, 100, '2009-01-01 00:00:00', 3 0
10, 100, '2010-01-01 00:00:00',3 0
11, 100, '2011-01-01 00:00:00',3 0
12, 100, '2012-01-01 00:00:00',3 0
13, 100, '2013-01-01 00:00:00',3 0
14, 100, '2014-01-01 00:00:00',3 1
15, 100, '2015-01-01 00:00:00',3 2
16, 100, '2016-01-01 00:00:00',3 3 (today is 2016-01-06)
Edit #2: This works to get the answer I need, but does not use a window partition. I'm thinking PostgreSQL does not implement the RANGE
with intervals - which is what I think this problem requires.
select s1.recid, s1.tservice, s1.client_recid,
(select count(*) from simpletable s2
where (s1.tservice - s2.tservice)::INTERVAL <= interval '3 years' and
s2.tservice < s1.tservice and
s2.client_recid = s1.client_recid)
from simpletable s1
order by client_recid, tservice
On a couple hundred thousand records, this takes about 10 seconds on my laptop. Is there a faster way?
Addendum Note: Using the functional approach with a cursor as outlined by Erwin reduced the execution time to 146ms. Thanks everybody for an excellent tutorial.