- Growing Customers: Customers which have been increasing their sales in the last six months. The sales increment should be greater than 5%.
- Shrinking Customers: Customers which have been decreasing their sales in the last six months. The sales decrement should be less than 5%.
- Regular Customers: The remaining customers, it means customers that don’t grow or shrink.
In this article, the samples are using the Adventure Works DW Analysis Services Database. For more information about this sample database see SQL Server Books on Line.
First we explain the basic linear regression concepts used to determine whether a customer is growing or not, and to determine if the growing rate exceeds the 5% threshold for the growing customer or the shrinking rate is less than the 5%. Then there are some basic concepts regarding the Time dimension and finally we apply the concepts to the solution.
Linear Regression Concepts
Given the linear regression equation: y = ax + b
For more information about the use of linear regression functions see Mosha Pasumansky’s article: Using Linear Regression MDX functions for forecasting at http://www.sqljunkies.com/WebLog/mosha/archive/2004/12/21/5689.aspx
Our purpose is to use the sales values for each customer over the lasts six months, obtain the Slope from a linear regression and determine if a given customer is growing or shrinking. Thus, if the slope is greater than zero the customer is growing, and if it is les than zero is shrinking. However, based on the business rules, we need to introduce a 5% tolerance for the growing and shrinking rates.
Considering sales in the current period of time (CurrentSales), and comparing it to sales in the previous period (PreviousSales), we can calculate the variation rate like this:
VariationRate = (CurrentSales / PreviousSales) - 1
Then
The MDX expression to obtain the last period at Month level is:
[Date].[Calendar].CurrentMember)
SET [LastPeriodsSet] AS
LastPeriods(Measures.NumberOfPeriods,
ClosingPeriod([Date].[Calendar].[Month],
[Date].[Calendar].CurrentMember)
)
The Solution
Now we can use the linear regression functions together with the sales over the date.calendar hierarchy and solve the problem.
LinRegSlope([LastPeriodsSet],
[Measures].[Sales Amount],
Rank([Date].[Calendar].CurrentMember,
[Date].[Calendar].CurrentMember.Level.Members)
)
LinRegIntercept([LastPeriodsSet],
[Measures].[Sales Amount],
Rank([Date].[Calendar].CurrentMember,
[Date].[Calendar].CurrentMember.Level.Members)
)
MEMBER Measures.VariationRate AS
Measures.Slope / Measures.Intercept
Finally we are ready to create three sets of customers: Shrinking customers, Growing and Regular. This is done using the slope sign, which is negative for shrinking, positive for growing, and if the variation is not as big as the threshold the customers are considered regular. The following code creates these sets:
MEMBER Measures.Threshold as 0.05
SET [ShrinkingCustomers]
AS FILTER([Customer].[Customer].[All Customers].CHILDREN,
Measures.Slope < 0
AND Measures.VariationRate < - Measures.Threshold)
SET [GrowingCustomers]
AS FILTER([Customer].[Customer].[All Customers].CHILDREN,
Measures.Slope > 0
AND Measures.VariationRate > Measures.Threshold)
SET [RegularCustomers]
AS EXCEPT([Customer].[Customer].[All Customers].CHILDREN,
[ShrinkingCustomers] + [GrowingCustomers])
[Measures].[Sales Amount] ON COLUMNS,
{[ShrinkingCustomers]} ON ROWS
FROM [Adventure Works]
MEMBER Measures.NumberOfPeriods AS 6
SET [LastPeriodsSet] AS
LastPeriods(Measures.NumberOfPeriods,
ClosingPeriod([Date].[Calendar].[Month],
[Date].[Calendar].CurrentMember)
)
MEMBER Measures.Slope AS
LinRegSlope([LastPeriodsSet],
[Measures].[Sales Amount],
Rank([Date].[Calendar].CurrentMember, [Date].[Calendar].CurrentMember.Level.Members)
)
MEMBER Measures.Intercept AS
LinRegIntercept([LastPeriodsSet],
[Measures].[Sales Amount],
Rank([Date].[Calendar].CurrentMember, [Date].[Calendar].CurrentMember.Level.Members)
)
MEMBER Measures.Threshold as 0.0005
MEMBER Measures.VariationRate AS
Measures.Slope / Measures.Intercept
SET [ShrinkingCustomers]
AS FILTER([Customer].[Customer].[All Customers].CHILDREN,
Measures.Slope < 0
AND Measures.VariationRate < - Measures.Threshold)
SET [GrowingCustomers]
AS FILTER([Customer].[Customer].[All Customers].CHILDREN,
Measures.Slope > 0
AND Measures.VariationRate > Measures.Threshold)
SET [RegularCustomers]
AS EXCEPT([Customer].[Customer].[All Customers].CHILDREN,
[ShrinkingCustomers] + [GrowingCustomers])
SELECT
{[Measures].[Sales Amount],
Measures.Slope,
Measures.VariationRate} ON COLUMNS,
{[GrowingCustomers]} ON ROWS
FROM [Adventure Works]