| Author |
Topic |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-04-02 : 13:39:51
|
I’m checking to see if anyone might know of a good way to accomplish what I’m trying to do. I have Customers and Orders. A customer might be the one who ordered a product or whom the product was sold to (yes they can be different. Think of a person ordering for a company). Now my requirement is to find the customers that Lapsed. A Lapsed customer is defined as a customer that has not made a purchase within 2-times their average time period between purchases. For example, if a customers purchase frequency averages 180 days. Then if they have not made a purchase within 360 days of today (2 x 180), then they are lapsed. Hopefully, that makes sense. If you need more information, just ask.Here is some sample data (Just ignore customer ID 6):DECLARE @Customer TABLE( CustomerID INT NOT NULL PRIMARY KEY)DECLARE @Order TABLE( OrderID INT NOT NULL PRIMARY KEY, OrderDateNumber INT NOT NULL, OrderedByCustomerID INT NOT NULL, SoldToCustomerID INT NOT NULL)INSERT @CustomerSELECT 1UNION ALL SELECT 2UNION ALL SELECT 3UNION ALL SELECT 4UNION ALL SELECT 5INSERT @OrderSELECT 1, 20070702, 2, 6UNION ALL SELECT 2, 20040805, 3, 3UNION ALL SELECT 3, 20071031, 2, 6UNION ALL SELECT 4, 20080228, 2, 6UNION ALL SELECT 5, 20070316, 2, 6UNION ALL SELECT 6, 20070425, 5, 6UNION ALL SELECT 7, 20070523, 5, 6UNION ALL SELECT 8, 20070418, 3, 6UNION ALL SELECT 9, 20051019, 3, 3UNION ALL SELECT 10, 20010226, 2, 6UNION ALL SELECT 11, 20050930, 3, 3UNION ALL SELECT 12, 20050819, 3, 3UNION ALL SELECT 13, 20060510, 3, 6UNION ALL SELECT 14, 20070608, 2, 6UNION ALL SELECT 15, 20061030, 3, 6UNION ALL SELECT 16, 20050824, 3, 3UNION ALL SELECT 17, 20061109, 5, 6UNION ALL SELECT 18, 20071120, 2, 6UNION ALL SELECT 19, 20050919, 4, 4UNION ALL SELECT 20, 20071105, 2, 6UNION ALL SELECT 21, 20071105, 2, 6UNION ALL SELECT 22, 20050923, 3, 3UNION ALL SELECT 23, 20050923, 3, 3UNION ALL SELECT 24, 20040809, 3, 3UNION ALL SELECT 25, 20050715, 3, 3UNION ALL SELECT 26, 20000731, 2, 6UNION ALL SELECT 27, 20011114, 2, 6UNION ALL SELECT 28, 20040916, 4, 4UNION ALL SELECT 29, 20071105, 2, 6UNION ALL SELECT 30, 20070415, 3, 3UNION ALL SELECT 31, 20070717, 3, 6UNION ALL SELECT 32, 20080207, 4, 4UNION ALL SELECT 33, 20050802, 3, 3UNION ALL SELECT 34, 20041022, 4, 4UNION ALL SELECT 35, 20060510, 2, 6UNION ALL SELECT 36, 20061017, 4, 4UNION ALL SELECT 37, 20050228, 3, 3UNION ALL SELECT 38, 20070109, 5, 6UNION ALL SELECT 39, 20071115, 2, 6UNION ALL SELECT 40, 20080225, 4, 4UNION ALL SELECT 41, 20030820, 3, 3UNION ALL SELECT 42, 20071106, 2, 6UNION ALL SELECT 43, 20070209, 5, 6UNION ALL SELECT 44, 20070628, 4, 6UNION ALL SELECT 45, 20051028, 3, 3UNION ALL SELECT 46, 20051103, 3, 3UNION ALL SELECT 47, 20070703, 2, 6UNION ALL SELECT 48, 20080207, 2, 6UNION ALL SELECT 49, 20070711, 3, 3UNION ALL SELECT 50, 20070417, 3, 3UNION ALL SELECT 51, 20051013, 3, 3UNION ALL SELECT 52, 20050719, 3, 3UNION ALL SELECT 53, 20071130, 2, 6UNION ALL SELECT 54, 20070725, 2, 6UNION ALL SELECT 55, 20070713, 3, 3UNION ALL SELECT 56, 20070522, 5, 6UNION ALL SELECT 57, 20050819, 3, 3UNION ALL SELECT 58, 20050823, 4, 4UNION ALL SELECT 59, 20041109, 3, 3UNION ALL SELECT 60, 20031023, 4, 4UNION ALL SELECT 61, 20000523, 2, 6UNION ALL SELECT 62, 20051007, 3, 3UNION ALL SELECT 63, 20050727, 3, 3UNION ALL SELECT 64, 20051027, 3, 3UNION ALL SELECT 65, 20021112, 3, 3UNION ALL SELECT 66, 20050824, 3, 3UNION ALL SELECT 67, 20070615, 5, 6UNION ALL SELECT 68, 20050428, 2, 6UNION ALL SELECT 69, 20060324, 3, 3UNION ALL SELECT 70, 20070215, 5, 6UNION ALL SELECT 71, 20070713, 3, 6UNION ALL SELECT 72, 20050930, 3, 3UNION ALL SELECT 73, 20070613, 2, 6 Here is the expected output(EDIT for correct output):CustomerID35 Here are some more detailed results to see some of the calculations I performed:CustomerID MaxOrderDate OrderFrequencyInDays DateDiffOfLastOrder TwoTimesFrequency IsLapsed-------------------------------------------------------------------------------------------2 2008-02-28 141.850000 34 283.700000 03 2007-07-17 58.896551 260 117.793102 14 2008-02-25 176.222222 37 352.444444 05 2007-06-15 27.250000 292 54.500000 1 Yes, I already have a solution, but I didn’t want to post it yet because I didn’t want skew anyone’s answer. :)PS, Sorry for the long post, but I wanted to provide some decent sample data. |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-04-02 : 14:29:16
|
| Where is this Order Frequency field coming from? or is it a calculated one? |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-04-02 : 15:27:33
|
I think OrderFrequence is (MAX(Date) - MIN(Date)) / COUNT(*)I think DateDiff is MAX(Date) - SECONDMAX(Date).I have no idea what the other two columns are and how they are calculated. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-04-02 : 15:35:45
|
Yeah, that is soemthing I calculate. It's the average numbe of days between orders for that customer.For grins here is an example:OrderDate---------200701012007011020070115So I take 20070110 - 20070101 = 10 days20070115 - 20070110 = 5 days15 days total / 3 orders for an average of 5 days (or as I listed above OrderFrequencyInDays)I'll try to explain the other columns as didn;t doa very good job of that.Hopefully MaxOrderDate is obvious. :)The DateDif is the difference of GETDATE() and MaxOrderDate in days.The TwoTimesFrequency is just 2 * the OrderFrequenceyInDays.The IsLapsed is true if the DateDiff is less greater than the TwoTimesFrequency.Hope that helps. |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2008-04-02 : 16:39:12
|
| are you sure that the OrderFrequencyInDays is correct for customers 2 and 3 in your example?_______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenpSSMS Add-in that does a few things: www.ssmstoolspack.com |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2008-04-02 : 16:55:00
|
| acctually i think it's wrong for all of them. or i'm missing a part of a requirement here..._______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenpSSMS Add-in that does a few things: www.ssmstoolspack.com |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2008-04-02 : 17:14:44
|
2 and 3 are not as yours are but 4 and 5 are...DECLARE @Customer TABLE( CustomerID INT NOT NULL PRIMARY KEY)DECLARE @Order TABLE( OrderID INT NOT NULL PRIMARY KEY, OrderDateNumberOld int NOT NULL, OrderedByCustomerID INT NOT NULL, SoldToCustomerID INT NOT NULL, OrderDateNumber datetime NULL)INSERT @CustomerSELECT 1UNION ALL SELECT 2UNION ALL SELECT 3UNION ALL SELECT 4UNION ALL SELECT 5INSERT INTO @Order (OrderID, OrderDateNumberOld, OrderedByCustomerID, SoldToCustomerID)SELECT 1, 20070702, 2, 6UNION ALL SELECT 2, 20040805, 3, 3UNION ALL SELECT 3, 20071031, 2, 6UNION ALL SELECT 4, 20080228, 2, 6UNION ALL SELECT 5, 20070316, 2, 6UNION ALL SELECT 6, 20070425, 5, 6UNION ALL SELECT 7, 20070523, 5, 6UNION ALL SELECT 8, 20070418, 3, 6UNION ALL SELECT 9, 20051019, 3, 3UNION ALL SELECT 10, 20010226, 2, 6UNION ALL SELECT 11, 20050930, 3, 3UNION ALL SELECT 12, 20050819, 3, 3UNION ALL SELECT 13, 20060510, 3, 6UNION ALL SELECT 14, 20070608, 2, 6UNION ALL SELECT 15, 20061030, 3, 6UNION ALL SELECT 16, 20050824, 3, 3UNION ALL SELECT 17, 20061109, 5, 6UNION ALL SELECT 18, 20071120, 2, 6UNION ALL SELECT 19, 20050919, 4, 4UNION ALL SELECT 20, 20071105, 2, 6UNION ALL SELECT 21, 20071105, 2, 6UNION ALL SELECT 22, 20050923, 3, 3UNION ALL SELECT 23, 20050923, 3, 3UNION ALL SELECT 24, 20040809, 3, 3UNION ALL SELECT 25, 20050715, 3, 3UNION ALL SELECT 26, 20000731, 2, 6UNION ALL SELECT 27, 20011114, 2, 6UNION ALL SELECT 28, 20040916, 4, 4UNION ALL SELECT 29, 20071105, 2, 6UNION ALL SELECT 30, 20070415, 3, 3UNION ALL SELECT 31, 20070717, 3, 6UNION ALL SELECT 32, 20080207, 4, 4UNION ALL SELECT 33, 20050802, 3, 3UNION ALL SELECT 34, 20041022, 4, 4UNION ALL SELECT 35, 20060510, 2, 6UNION ALL SELECT 36, 20061017, 4, 4UNION ALL SELECT 37, 20050228, 3, 3UNION ALL SELECT 38, 20070109, 5, 6UNION ALL SELECT 39, 20071115, 2, 6UNION ALL SELECT 40, 20080225, 4, 4UNION ALL SELECT 41, 20030820, 3, 3UNION ALL SELECT 42, 20071106, 2, 6UNION ALL SELECT 43, 20070209, 5, 6UNION ALL SELECT 44, 20070628, 4, 6UNION ALL SELECT 45, 20051028, 3, 3UNION ALL SELECT 46, 20051103, 3, 3UNION ALL SELECT 47, 20070703, 2, 6UNION ALL SELECT 48, 20080207, 2, 6UNION ALL SELECT 49, 20070711, 3, 3UNION ALL SELECT 50, 20070417, 3, 3UNION ALL SELECT 51, 20051013, 3, 3UNION ALL SELECT 52, 20050719, 3, 3UNION ALL SELECT 53, 20071130, 2, 6UNION ALL SELECT 54, 20070725, 2, 6UNION ALL SELECT 55, 20070713, 3, 3UNION ALL SELECT 56, 20070522, 5, 6UNION ALL SELECT 57, 20050819, 3, 3UNION ALL SELECT 58, 20050823, 4, 4UNION ALL SELECT 59, 20041109, 3, 3UNION ALL SELECT 60, 20031023, 4, 4UNION ALL SELECT 61, 20000523, 2, 6UNION ALL SELECT 62, 20051007, 3, 3UNION ALL SELECT 63, 20050727, 3, 3UNION ALL SELECT 64, 20051027, 3, 3UNION ALL SELECT 65, 20021112, 3, 3UNION ALL SELECT 66, 20050824, 3, 3UNION ALL SELECT 67, 20070615, 5, 6UNION ALL SELECT 68, 20050428, 2, 6UNION ALL SELECT 69, 20060324, 3, 3UNION ALL SELECT 70, 20070215, 5, 6UNION ALL SELECT 71, 20070713, 3, 6UNION ALL SELECT 72, 20050930, 3, 3UNION ALL SELECT 73, 20070613, 2, 6-- set int to datetimeupdate @order set OrderDateNumber = convert(datetime, left(OrderDateNumberOld, 4) + right(left(OrderDateNumberOld, 6), 2) + right(OrderDateNumberOld, 2))declare @boundryDates table (CustomerId int, MinDate datetime, MaxDate datetime, OrderCount decimal(14, 2))insert @boundryDatesselect C.CustomerId, min(O.OrderDateNumber), max(O.OrderDateNumber), count(*)from @Order O join @Customer C on C.CustomerID in (OrderedByCustomerID, SoldToCustomerID) group by C.CustomerIdselect CustomerId, convert(decimal(14, 2), datediff(day, MinDate, MaxDate)/OrderCount) as OrderFrequencyInDays, convert(decimal(14, 2), (datediff(day, MinDate, MaxDate)/OrderCount)) * 2 as TwoTimesFrequency, datediff(day, MaxDate, GETDATE()) as DateDiffOfLastOrder from @boundryDates select CustomerIdfrom( select CustomerId, convert(decimal(14, 2), datediff(day, MinDate, MaxDate)/OrderCount) as OrderFrequencyInDays, convert(decimal(14, 2), (datediff(day, MinDate, MaxDate)/OrderCount)) * 2 as TwoTimesFrequency, datediff(day, MaxDate, GETDATE()) as DateDiffOfLastOrder from @boundryDates ) t1where DateDiffOfLastOrder > TwoTimesFrequency _______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenpSSMS Add-in that does a few things: www.ssmstoolspack.com |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-04-02 : 17:17:48
|
Good question, I belive that they are all correct. And I think I know what is missing from my requirements...For CustomerID 2 they had 3 orders on 20071105. I'm only interested in a "puchase day." So, for N number of orders for a particular customer on a particular day is only counted once. So, I'm grouping by day: SELECT DISTINCT OrderDateNumber FROM @OrderWHERE SoldToCustomerID = 2 OR OrderedByCustomerID = 2 I appreciate you guys taking a look and I'm sorry the logic is not explained the best way. |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2008-04-02 : 17:20:00
|
simple correction then:declare @boundryDates table (CustomerId int, MinDate datetime, MaxDate datetime, OrderCount decimal(14, 2))insert @boundryDatesselect C.CustomerId, min(O.OrderDateNumber), max(O.OrderDateNumber), count( distinct O.OrderDateNumber)from @Order O join @Customer C on C.CustomerID in (OrderedByCustomerID, SoldToCustomerID) group by C.CustomerIdselect CustomerId, convert(decimal(14, 2), datediff(day, MinDate, MaxDate)/OrderCount) as OrderFrequencyInDays, convert(decimal(14, 2), (datediff(day, MinDate, MaxDate)/OrderCount)) * 2 as TwoTimesFrequency, datediff(day, MaxDate, GETDATE()) as DateDiffOfLastOrder from @boundryDates select CustomerIdfrom( select CustomerId, convert(decimal(14, 2), datediff(day, MinDate, MaxDate)/OrderCount) as OrderFrequencyInDays, convert(decimal(14, 2), (datediff(day, MinDate, MaxDate)/OrderCount)) * 2 as TwoTimesFrequency, datediff(day, MaxDate, GETDATE()) as DateDiffOfLastOrder from @boundryDates ) t1where DateDiffOfLastOrder > TwoTimesFrequency _______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenpSSMS Add-in that does a few things: www.ssmstoolspack.com |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-04-02 : 17:53:18
|
| Nice! Thanks Spirit, That's pretty similar to what I had come up with. Although, mine had a couple of extra superfolous bits as I couldn't see the forest through the trees. :) |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2008-04-02 : 18:04:21
|
you're welcome!do show yours _______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenpSSMS Add-in that does a few things: www.ssmstoolspack.com |
 |
|
|
|
|
|