- 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
The linear regression equation gives us a measurement of sales for each period of time. Thus X0 is the first period, X1 the second, and so on. Then we can calculate the VariationRate in terms of the y = ax + b equation like:
Because we are using a linear regression, we can suppose that the VariationRate remains the same if we use any pair of contiguous values in the X axis. So we can use X0 and X1 values and assume that X0 = 0 and X1 = 1. Replacing these values in the VariationRate equation we have:
Then
Going back to our table of functions, we can use LineRegSlope and LineRegIntercept to calculate the VariationRate and determine which customers grow more than 5% or shrink less than 5%.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]