Reputation: 21
I have a table about members subscriptions which has four main columns :
1-member_id
2-subscription_no
3-subscription_start_date
4-subscription_end_Date
And every member(has an unique member id) may have more than one subscription so I need to get the latest subscription date for every member .
Now my scenario is like this:
I need to get the members who did not subscribed again after 5 months of the his active subscription during 2012.
I.e I need to know the members who the company has lost them as subscribers as the criteria of being lost is not subscribe after 5 months of the end of his last active subscription during 2012.
Upvotes: 0
Views: 492
Reputation: 133
I did some tests depending on your schenario as bellow
create table table1 (id integer, nm integer, stdate date, endate date);
inserted some test data
Insert into TABLE1(ID, NM, STDATE, ENDATE)
Values (1, 2, TO_DATE('04/09/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('06/17/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into TABLE1(ID, NM, STDATE, ENDATE)
Values(1, 1, TO_DATE('03/25/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('06/14/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into TABLE1(ID, NM, STDATE, ENDATE)
Values(2, 3, TO_DATE('03/05/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('06/15/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into TABLE1(ID, NM, STDATE, ENDATE)
Values(2, 2, TO_DATE('03/06/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('06/28/2013 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
COMMIT;
And the query is
with q1 as (
select id, nm, stdate, endate,
row_number() over (partition by id order by endate desc) as rn
from table1
) select * from q1 where rn=1
and <last5 months criteria using endate>;
result of the query
select id, nm, stdate, endate,
row_number() over (partition by id order by endate desc) as rn
from table1
will give the following result, then you can filter the result using the rn column and last 5 months criteria.
id nm sdate endate rn
1 2 09.04.2013 17.06.2013 1
1 1 25.03.2013 14.06.2013 2
2 2 06.03.2013 28.06.2013 1
2 3 05.03.2013 15.06.2013 2
Upvotes: 1
Reputation: 330
You could use the following select.
select member_id, max(subscription_end_Date)
from yourTable
where subscription_end_Date>= trunc(trunc(sysdate,'year')-1,'year')
group by member_id having months_between(sysdate,max(subscription_end_Date))>=5;
where the trunc(trunc(sysdate,'year')-1,'year')
returns the first day of last year.
By using the trunc condition, the query selects only the members that have at least one subscription with subscription_end_Date > '01 - JAN - 2012' and by using the months_between(sysdate,max(subscription_end_Date))>=5
it returns only those that have not subscribed for at least 5 months from last subscription_end_Date.
HTH!
Upvotes: 1
Reputation: 7940
This should do your job [Assuming that query will be executed now as 5 months have passed this year], whole logic is that max subscription end date lies in 2012:
select member_id from (
select member_id, max(subscription_end_Date) ed, max(subscription_start_Date) sd
from yourTable
group by member_id) a
where trunc(ed, 'YEAR') = 2012 and sd <= add_months(ed,5)
Upvotes: 0
Reputation: 20794
Something like this should work.
select old.member_id
from subscription old left join subscription renew on old.member_id = renew.member_id
and renew.start_date <= old.end_date + 165 -- (roughly 5 months)
where old.end_date >= {d '2012-01-01'}
and old.end_date < {d '2013-01-01'}
and renew.start_date is null
oracle might not like that date format, but this should be the correct logic.
Upvotes: 0