I would like to assign customers into one of these five groups, based on their historical purchases. Here are the definitions of those five groups.
- Lost - purchased in the prior 12 month period, but not current 12 month period
- New - purchased in current 12 month period and has no purchases prior to that
- Restarted (1 year) - purchased in current 12 month period, did not purchase in the 12 month period before that (13-24 months ago), but did purchase 25-36 months ago
- Restarted (other) - purchased in current 12 month period, did not purchase in the 12 month period before that (13-24 months ago), but did purchase at some other point historically
- Continuing - purchased in the current 12 month period and the previous 12 month period
| Account_no | Group |
| ------------ | ------------ |
| 123 | New |
| 124 | Lapsed |
| 544 | Returning_1yr |
My current code gets a list of accounts for each group into their own temp table. I thought I might be able to use a 'case when' within select to create the 'Group' field that I'm trying to create, but that's where I got stuck. I'm sure there's a more elegant solution than what I'm doing here, so certainly open to suggestions. Thank you!
/*Group customers who bought in current 12 month window*/
drop table if exists #current12
select distinct txn.account_no
into #current12
from transactions txn
where tran_date between dateadd(day,-365,getdate()) and getdate()
/*Group customers who bought in previous 12 month window (13 - 24 months ago)*/
drop table if exists #previous12
select distinct txn.account_no
into #previous12
from transactions txn
where tran_date between dateadd(day,-730,getdate()) and dateadd(day,-366,getdate())
/*Group customers who bought in prior 12 month window (25 - 36 months ago)*/
drop table if exists #prior12
select distinct txn.account_no
into #prior12
from transactions txn
where tran_date between dateadd(day,-1095,getdate()) and dateadd(day,-731,getdate())
/*Group customers who bought at any time before current 12 month window (13+ months ago)*/
drop table if exists #beforecurrent12
select distinct txn.account_no
into #beforecurrent12
from transactions txn
where tran_date < dateadd(day,-365,getdate())
/*Create table of lost customers*/
drop table if exists #lost
select distinct txn.account_no
into #lost
from transactions txn
where txn.account_no IN (select account_no from #previous12)
and txn.account_no NOT IN (select account_no from #current12)
/*Create table of new customers*/
drop table if exists #new
select distinct txn.account_no
into #new
from transactions txn
where txn.account_no IN (select account_no from #current12)
and txn.account_no NOT IN (select distinct account_no from client.dbo.acct_sales_trans where tran_date < dateadd(day,-366,getdate()))
/*Create table of restarted 1 yr customers*/
drop table if exists #restarted1yr
select distinct txn.account_no
into #restarted1yr
from transactions txn
where txn.account_no IN (select account_no from #current12)
and txn.account_no NOT IN (select account_no from #previous12)
and txn.account_no IN (select account_no from #prior12)
/*Create table of restarted other customers*/
drop table if exists #restartedother
select distinct txn.account_no
into #restartedother
from transactions txn
where txn.account_no IN (select account_no from #current12)
and txn.account_no NOT IN (select account_no from #previous12)
and txn.account_no NOT IN (select account_no from #prior12)
and txn.account_no IN (select distinct account_no from transactions where tran_date < dateadd(day,-1095,getdate()))
/*Create table of returning customers*/
drop table if exists #returning
select distinct txn.account_no
into #returning
from transactions txn
where txn.account_no IN (select account_no from #previous12)
and txn.account_no IN (select account_no from #current12)
2条答案
按热度按时间fcg9iug31#
Rather than trying to define each Grouping as a new temp table I'd be tempted to do something more like for each account flagging if they made purchase in each year. Then using these flags to identify which group they should be in.
In this code I've left the individual flags as well as the CustomerGroup. I would use the flags to sanity check the logic on the grouping CASE.
There is a customer group for other that under the current definition will include anyone who has not purchased in year 1 nor 2, but has made an older purchase. You may want to include this filter
ryoqjall2#
It's really helpful for questions like this to include sample DDL and DML. Based on your description I put together this as example data. I've used table variables because there's less to clean up, but that's just a personal preference.
Using that, I then crafted a case expression to look over several LEFT OUTER joins to the orders which capture the specifics you talked about:
We're joining to the orders table several times for the periods you mention, and then just doing a simple count for each of the periods. The case expression then returns the status dependent on what's found.
You may want to tweak exactly how the joins work to tweak it to better fit your needs.