Кажется, что-то подобное делает то, что вы хотите:
Настройка теста:
create table loans
(
customer_id integer,
date_disbursed date
);
insert into loans
values
( 1, date '2016-01-01'),
( 2, date '2016-01-02'),
( 3, date '2016-01-04'),
( 4, date '2016-01-08'),
( 5, date '2016-01-12'),
( 6, date '2016-01-18'),
( 7, date '2016-02-08'),
( 8, date '2016-02-12'),
( 9, date '2016-03-18'),
(10, date '2016-03-12'),
(11, date '2016-03-18'),
( 3, date '2016-03-04'),
( 4, date '2016-03-08'),
( 5, date '2016-03-12'),
( 5, date '2016-04-12'),
(12, date '2016-04-12'),
( 5, date '2016-05-12'),
( 6, date '2016-05-18');
Запрос:
select to_char(date_disbursed, 'yyyy-mm') as month,
count(*) filter (where new_customer) as new_customers,
count(*) filter (where recurring_customer) as returning_customers
from (
select customer_id,
date_disbursed,
date_disbursed = min(date_disbursed) over w as new_customer,
date_disbursed > min(date_disbursed) over w as recurring_customer
from loans
window w as (partition by customer_id)
) t
group by to_char(date_disbursed, 'yyyy-mm')
order by to_char(date_disbursed, 'yyyy-mm');
возвращает
month | new_customers | returning_customers
--------+---------------+--------------------
2016-01 | 6 | 0
2016-02 | 2 | 0
2016-03 | 3 | 3
2016-04 | 1 | 1
2016-05 | 0 | 2