Reputation: 181
For my problem I'll try to create a simplified example.
Table "order":
ID | date | client | product | product_limit_period (in months)
1 | 2015-01-01 | Bob | table | 1
2 | 2015-01-31 | Bob | table | 1
3 | 2015-02-01 | Bob | table | 1
4 | 2015-01-01 | Mary | lamb | 12
5 | 2015-06-01 | Mary | lamb | 12
6 | 2016-01-01 | Mary | lamb | 12
7 | 2016-12-31 | Mary | lamb | 12
This is the result, I'd like to get:
client | product | group | count
Bob | table | 1 | 2 #ID 1, 2
Bob | table | 2 | 1 #ID 3
Mary | lamb | 3 | 2 #ID 4, 5
Mary | lamb | 4 | 2 #ID 6, 7
Every product has a limit and a limit period (in months). I need to be able to see if there are any clients that have ordered a product more than its limit allows in a certain period. The period in months might be 1 month or several years in months. It is possible that the period is 1 month, 12 months, 24 months, ... until 108 months (9 years).
I feel like I need to use some combination of window functions and group by. But I haven't figured out how.
I'm using postgres 9.1. Please let me know if there is any more information I should provide.
Any help is appreciated, even just pointing me to the right direction!
Edit:
To clarify how the grouping works: The limit period starts with the first order. Bob's first order is 2015-01-01 and so this period ends with 2015-01-31. 2015-02-01 starts a second period. A period always starts with the first day of a month and ends with the last day of a month.
Upvotes: 0
Views: 253
Reputation: 51649
no need to complicate with both window and group by, just add case
to either a window or group, like here:
t=# select
client
, product
, count(1)
, string_agg(id::text,',')
from so44
group by
client
, product
, date_trunc(case when product_limit_period = 1 then 'month' else 'year' end,date);
client | product | count | string_agg
----------+-----------+-------+------------
Bob | table | 2 | 1,2
Bob | table | 1 | 3
Mary | lamb | 2 | 4,5
Mary | lamb | 2 | 6,7
(4 rows)
sample:
t=# create table so44 (i int,"date" date,client text,product text,product_limit_period int);
CREATE TABLE
t=# copy so44 from stdin delimiter '|';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> 1 | 2015-01-01 | Bob | table | 1
>> 2 | 2015-01-31 | Bob | table | 1
3 | 2015-02-01 | Bob | table | 1
4 | 2015-01-01 | Mary | lamb | 12
5 | 2015-06-01 | Mary | lamb | 12
6 | 2016-01-01 | Mary | lamb | 12
7 | 2016-12-31 | Mary | lamb | 12>> >> >> >> >>
>> \.
COPY 7
Upvotes: 1