I have table with members level changes. It has historical changes of level of all members and date when change happened. For example I can list changes for member number 5:
select * from memberlevelhistory where member = 5
result:
member changedate level
5 2012-04-01 2
5 2012-03-01 3
5 2012-02-01 2
5 2011-02-01 6
5 2011-02-01 6
5 2010-03-15 6
5 2010-02-01 5
5 2010-01-01 5
5 2009-10-01 4
5 2009-08-27 2
5 2009-08-01 1
Last entry in history table is current level.
QUESTION:
How to list all members that had level higher or equal to 3 for period of 3 months or more ?
That is a simplified version of the question. To make it even more fun I need only members that didn’t drop below the starting level during this 3 month period. So if a member started the 3 month period with level 4 and is only level 3 on the last month then that member is excluded from the list.
Any help, even with the simplified question is much appreciated.
EXTENDED VERSION:
I also need this period of >=3 months of level >=3 happen inside last 6 months window.
This might be a case for
not exists. An entry is valid if there is not another entry with level less than currently selected record in next three months. This solves both requirements. There might be an issue with last entry per member where level is appropriate, but span is not known. I’ve decided to remove those records, but you might have other ideas.Sql Fiddle with example is here.
EDIT:
I have rewritten not exists() to left join and added ‘last entry lasting until today’ criterion.
Sql Fiddle with example is here.
Query rewritten:
And Sql Fiddle is here.
I believe that 100 and 101 should be included because both had a good run for 3 months and this was on in march which is six months before this moment.
What I did is to generate ranges when somebody had a good run, and then test this ranges for duration of 3 months or more and ending date in last six months.
UPDATE: if I finally got it right, you need that duration is lasting for three months in last six months. To calculate that one might truncate changedates to current date – six months. Using that as starting point, and finding ending point of a range as first
mlhhaving lower level and higher date as ending point one has enough information to calculate duration.Sql Fiddle with example is here.