Question: I have a `Payment` table that looks a little like this:

```
Id (int identity)
CustomerId (int)
PaymentDate (SmallDateTime)

```

Now I want to write a query that will find those customers that have made three payments within a period of three months. Given the following data:

```
Id   CustomerId   PaymentDate (YYYY-MM-DD)
------------------------------------------
1    1            2010-01-01
2    1            2010-02-01
3    1            2010-03-01
4    1            2010-06-01
5    2            2010-04-01
6    2            2010-05-01
7    2            2010-06-01
8    2            2010-07-01

```

I would like to produce the following result:

```
CustomerId    LastPaymentDateInPeriod
-------------------------------------
1             2010-03-01
2             2010-07-01

```

Where `LastPaymentDateInPeriod` is the `PaymentDate` with the highest value within a three-month period. If there is more than one three-month period for a given customer it would have to return the highest value from the most recent period (this is what I tried to illustrate for customer 2 in the above example). **Note** that three payments on three consecutive days would also meet the criteria. The payments just have to fall within a three-month period.

I know how to do this with a cursor and a lot of smaller queries but this is slow (and, I've come to understand, should only be a last resort). So do any of you SqlServer geniuses know how to do this with a query?

Thanks in advance.

Answer: 
This should do the job:

```
select 
    CustomerID,
    max(LastPaymentDateInPeriod) as LastPaymentDateInPeriod
from
(
    select
      LastPaymentInPeriod.CustomerID,
      LastPaymentInPeriod.PaymentDate as LastPaymentDateInPeriod
    from Payment LastPaymentInPeriod
      inner join Payment RelatedPayment on
        LastPaymentInPeriod.CustomerID = RelatedPayment.CustomerID and
        LastPaymentInPeriod.PaymentDate > RelatedPayment.PaymentDate and
        datediff(m, RelatedPayment.PaymentDate, LastPaymentInPeriod.PaymentDate) < 3
    group by
      LastPaymentInPeriod.CustomerID,
      LastPaymentInPeriod.PaymentDate
    having
      count(*) > 1

 ) as PaymentPeriods
group by
    CustomerID

```

**update:** I've tested this now and it seems to work for @Martin's data

**update2:** If it's a requirement that Jan 31 and Apr 1 should be considered as less than 3 months apart then the DATEDIFF function call can be replaced with something like this:

```
create function fn_monthspan
(
    @startdate datetime,
    @enddate datetime
)
returns int
as
begin
    return datediff(m, @startdate, @enddate) - case when datepart(d, @startdate) > datepart(d, @enddate) then 1 else 0 end
end

```
I thought of:

`select customerId,max(PaymentDate) from payment where customerId in  

(select case when count(*)<3 then null else customerId end as customerId from payment 
where paymentdate>dateadd(month,-3,getdate()) group by customerId)  

group by customerId;`