Reputation: 238
I have two table with columns as mentioned below:
CUSTOMER table as DIM_CUSTOMER:
ID_CUSTOMER, CUSTOMER_NAME
TRANSACTION table as FACT_TRANSACTION:
ID_CUSTOMER, DATE, TOTAL_PRICE, QUANTITY
Problem statement is to
Find top 100 customers and their average spend, average quantity by each year. Also find the percentage of change in their spend.
My approach:
SELECT TOP 100
YEAR(FT.DATE) AS [YEAR],
FT.ID_CUSTOMER AS [CUSTOMER NAME],
FT.TOTAL_PRICE AS [TOTAL AMT],
AVG(FT.TOTAL_PRICE) AS [AVG SPEND],
AVG(FT.QUANTITY) AS [AVG QUANTITY]
FROM
FACT_TRANSACTIONS FT
INNER JOIN
DIM_CUSTOMER DC ON FT.ID_CUSTOMER = DC.ID_CUSTOMER
GROUP BY
FT.DATE, FT.ID_CUSTOMER, FT.TOTAL_PRICE
ORDER BY
3 DESC
This is resulting in the top 100 customers based on their usage.
Now I need to determine the percentage change in their spend YEAR wise.
How can I do that? Probably using PIVOT option herein will help, but I'm unsure.
Upvotes: 0
Views: 666
Reputation: 6612
Can you please try following SQL CTE query ?
;with topcustomers as(
SELECT distinct top 100
ID_CUSTOMER,
SUM(TOTAL_PRICE) over (partition by ID_CUSTOMER) as TotalSPEND
FROM FACT_TRANSACTION
order by TotalSPEND desc
), cte as (
SELECT
distinct
t.ID_CUSTOMER, YEAR(t.DATE) [YEAR], TotalSPEND,
AVG(t.QUANTITY * 1.0) over (partition by t.ID_CUSTOMER, YEAR(t.DATE)) as AverageQUANTITY,
AVG(t.TOTAL_PRICE * 1.0) over (partition by t.ID_CUSTOMER, YEAR(t.DATE)) as AverageSPEND
FROM FACT_TRANSACTION t
INNER JOIN topcustomers c on c.ID_CUSTOMER = t.ID_CUSTOMER
)
select
*,
( AverageSPEND - lag(AverageSPEND,1) over (partition by ID_CUSTOMER order by [YEAR]) ) * 100.0 / AverageSPEND as [%Change]
from cte
Upvotes: 0
Reputation: 43636
You can try using LAG in order to access the previous [AVG SPEND]
for the current row. The idea is to group the data for each [CUSTOMER NAME]
using PARTITION BY
and then to order the data by the [YEAR]
. The function will give us the previous result and we can calculated easily the difference.
Try something like this:
SELECT TOP 100
YEAR(FT.DATE) AS [YEAR],
FT.ID_CUSTOMER AS [CUSTOMER NAME],
FT.TOTAL_PRICE AS [TOTAL AMT],
AVG(FT.TOTAL_PRICE) AS [AVG SPEND],
AVG(FT.QUANTITY) AS [AVG QUANTITY]
INTO #DataSource
FROM
FACT_TRANSACTIONS FT
INNER JOIN
DIM_CUSTOMER DC ON FT.ID_CUSTOMER = DC.ID_CUSTOMER
GROUP BY
YEAR(FT.DATE), FT.ID_CUSTOMER, FT.TOTAL_PRICE
ORDER BY
[AVG SPEND] DESC
SELECT *
,[AVG SPEND] - LAG([AVG SPEND], 1, 0) OVER (PARTITION BY [CUSTOMER NAME] ORDER BY [YEAR])
FROM #DataSource
Note, that:
ORDER BY [YEAR] DESC
LEAD
function in order to access the next value within the group if you want to calculated difference in advaceUpvotes: 1