Примечание. Это будет отправная точка и будет действовать только в 2011 году.
Игнорируя любые давние ошибки, этот код (для каждого клиента) просматривает 1) последнее обновление статуса клиента до мая и 2) активировался ли клиент в течение мая?
SELECT
Distinct CustId
FROM
MyTable -- Start with the Main table
-- So, was this customer active at the start of may?
LEFT JOIN -- Find this customer's latest entry before May of This Year
(select
max(Date)
from
MyTable
where
Date < '2011-05-01') as CustMaxDate_PreMay on CustMaxDate_PreMay.CustID = MyTable.CustID
-- Return a record "1" here if the Customer was Active on this Date
LEFT JOIN
(select
1 as Bool,
date
from
MyTable
) as CustPreMay_Activated on CustPreMay_Activated.Date = CustMaxDate_PreMay.Date and CustPreMay_Activated.CustID = MyTable.CustID and CustPreMay_Activated = 'activated'
-- Fallback plan: If the user wasn't already active at the start of may, did they turn active during may? If so, return a record here "1"
LEFT JOIN
(select
1 as Bool
from
MyTable
where
Date <= '2011-05-01' and Date < '2011-06-01' and action = 'activated') as TurnedActiveInMay on TurnedActiveInMay .CustID = MyTable.CustID
-- The Magic: If CustPreMay_Activated is Null, then they were not active before May
-- If TurnedActiveInMay is also Null, they did not turn active in May either
WHERE
ISNULL(CustPreMay_Activated.Bool, ISNULL(TurnedActiveInMay.Bool, 0)) = 1
Примечание:
Возможно, вам придется заменить `FROM MyTable 'на
From (Select distinct CustID from MyTable) as Customers
Мне неясно, просто глядя на этот код, будет ли он A) слишком медленным или B) каким-либо образом приводить к ошибкам или проблемам из-за запуска предложения FROM @ MYTable, которое может содержать много записей на одного клиента. Предложение DISTINCT, вероятно, позаботится об этом, но решил, что я бы упомянул об этом обходном пути.
Наконец, я оставлю вам возможность заниматься этой работой в разные годы.