✅ Understanding QVD file format
✅ Using MAPPING LOAD and APPLYMAP
✅ Creating calculated fields with IF statements
✅ Building calendar dimensions
✅ Using GROUP BY for aggregations
✅ Applying set analysis in charts
✅ Creating professional dashboards
Company Name: TechRetail Solutions Inc.
Industry: Consumer Electronics Retail
Business Model: Multi-channel retail (Online + Physical Stores)
Fiscal Year: January - December
TechRetail Solutions has been operating for 3 years across 5 regions (North, South, East, West, Central). The company sells electronics through:
The CFO has requested a comprehensive Sales Performance Dashboard to answer critical business questions for Q4 2024 planning.
You will work with 3 main data files (QVD format):
Create the following folders on your C: drive:
C:\Practice\
├── DataFiles\ (Source QVD files)
├── DataFiles\Transformed\ (Your transformed QVD files)
└── Scripts\ (Your QlikSense scripts)
C:\Practice\DataFiles\Copy this entire script into QlikSense Desktop Data Load Editor and run it once.
//====================================================================
// TECHRETAIL SOLUTIONS - PRACTICE DATA GENERATOR
// Purpose: Generates realistic sales data for training exercise
// Author: Training Team
// Date: January 2026
//====================================================================
//--- CONFIGURATION ---
SET ThousandSep=',';
SET DecimalSep='.';
SET MoneyThousandSep=',';
SET MoneyDecimalSep='.';
SET MoneyFormat='$#,##0.00';
SET DateFormat='DD-MM-YYYY';
LET vDataPath = 'C:\Practice\DataFiles\';
//--- ENSURE DIRECTORY EXISTS (Manual creation required) ---
// Please create C:\Practice\DataFiles\ folder before running this script
//====================================================================
// GENERATE PRODUCTS MASTER DATA
//====================================================================
[Products_Master]:
LOAD * INLINE [
Product_ID, Product_Name, Category, Sub_Category, Brand, Cost_Price, Retail_Price, Reorder_Level, Supplier_ID
P001, Smartphone X1, Electronics, Mobile Phones, TechBrand, 450, 699, 50, SUP01
P002, Smartphone X2 Pro, Electronics, Mobile Phones, TechBrand, 650, 999, 40, SUP01
P003, Laptop Ultra 15, Electronics, Laptops, CompuBrand, 800, 1299, 30, SUP02
P004, Laptop Pro 17, Electronics, Laptops, CompuBrand, 1200, 1899, 20, SUP02
P005, Tablet T10, Electronics, Tablets, TechBrand, 250, 399, 60, SUP01
P006, Smartwatch S1, Electronics, Wearables, FitBrand, 150, 249, 100, SUP03
P007, Wireless Earbuds, Electronics, Audio, SoundBrand, 50, 89, 200, SUP04
P008, Bluetooth Speaker, Electronics, Audio, SoundBrand, 80, 149, 80, SUP04
P009, USB-C Cable, Accessories, Cables, GenericBrand, 5, 15, 500, SUP05
P010, Phone Case Premium, Accessories, Cases, GenericBrand, 8, 25, 300, SUP05
P011, Wireless Mouse, Electronics, Peripherals, CompuBrand, 20, 39, 150, SUP02
P012, Mechanical Keyboard, Electronics, Peripherals, CompuBrand, 60, 119, 80, SUP02
P013, 4K Monitor 27", Electronics, Monitors, ViewBrand, 300, 499, 40, SUP06
P014, Webcam HD Pro, Electronics, Peripherals, ViewBrand, 45, 89, 100, SUP06
P015, External SSD 1TB, Electronics, Storage, StorageBrand, 90, 159, 120, SUP07
P016, Power Bank 20K, Accessories, Power, ChargeBrand, 25, 49, 200, SUP08
P017, Screen Protector, Accessories, Protection, GenericBrand, 3, 12, 400, SUP05
P018, HDMI Cable 2m, Accessories, Cables, GenericBrand, 8, 20, 250, SUP05
P019, Gaming Headset, Electronics, Audio, SoundBrand, 70, 129, 60, SUP04
P020, Portable Charger, Accessories, Power, ChargeBrand, 15, 35, 180, SUP08
] (delimiter is ',');
STORE [Products_Master] INTO [$(vDataPath)Products_Master.qvd] (qvd);
DROP TABLE [Products_Master];
//====================================================================
// GENERATE CUSTOMERS MASTER DATA
//====================================================================
[Customers_Master]:
LOAD * INLINE [
Customer_ID, Customer_Name, Customer_Type, Region, City, State, Join_Date, Email, Phone, Loyalty_Tier
C0001, John Smith, Individual, North, Boston, MA, 15-01-2023, [email protected], 555-0101, Gold
C0002, Sarah Johnson, Individual, North, New York, NY, 22-03-2023, [email protected], 555-0102, Silver
C0003, Michael Brown, Individual, South, Atlanta, GA, 10-02-2023, [email protected], 555-0103, Bronze
C0004, Emily Davis, Individual, East, Philadelphia, PA, 05-04-2023, [email protected], 555-0104, Gold
C0005, David Wilson, Individual, West, Los Angeles, CA, 18-01-2023, [email protected], 555-0105, Platinum
C0006, Lisa Anderson, Individual, Central, Chicago, IL, 25-02-2023, [email protected], 555-0106, Silver
C0007, James Martinez, Individual, South, Houston, TX, 12-03-2023, [email protected], 555-0107, Bronze
C0008, Jennifer Taylor, Individual, West, San Francisco, CA, 08-05-2023, [email protected], 555-0108, Gold
C0009, Robert Thomas, Individual, North, Boston, MA, 30-01-2023, [email protected], 555-0109, Silver
C0010, Mary Jackson, Individual, East, Washington, DC, 14-04-2023, [email protected], 555-0110, Bronze
C0011, Tech Corp Inc, Corporate, Central, Chicago, IL, 20-01-2023, [email protected], 555-0201, Platinum
C0012, Digital Solutions LLC, Corporate, West, Seattle, WA, 15-02-2023, [email protected], 555-0202, Gold
C0013, Metro University, Corporate, North, New York, NY, 28-02-2023, [email protected], 555-0203, Gold
C0014, Healthcare Plus, Corporate, South, Miami, FL, 10-03-2023, [email protected], 555-0204, Silver
C0015, Finance Group, Corporate, East, Philadelphia, PA, 22-03-2023, [email protected], 555-0205, Platinum
C0016, Patricia White, Individual, Central, St Louis, MO, 05-06-2023, [email protected], 555-0111, Bronze
C0017, Christopher Lee, Individual, West, Denver, CO, 18-06-2023, [email protected], 555-0112, Silver
C0018, Amanda Hall, Individual, South, Dallas, TX, 22-07-2023, [email protected], 555-0113, Gold
C0019, Daniel Young, Individual, North, Portland, ME, 15-08-2023, [email protected], 555-0114, Bronze
C0020, Nancy King, Individual, East, Baltimore, MD, 30-08-2023, [email protected], 555-0115, Silver
C0021, StartUp Ventures, Corporate, West, San Jose, CA, 12-04-2023, [email protected], 555-0206, Silver
C0022, Retail Chain Co, Corporate, Central, Indianapolis, IN, 25-04-2023, [email protected], 555-0207, Gold
C0023, Manufacturing Ltd, Corporate, South, Charlotte, NC, 08-05-2023, [email protected], 555-0208, Silver
C0024, Education Board, Corporate, North, Buffalo, NY, 19-05-2023, [email protected], 555-0209, Bronze
C0025, Legal Associates, Corporate, East, Richmond, VA, 02-06-2023, [email protected], 555-0210, Gold
] (delimiter is ',');
STORE [Customers_Master] INTO [$(vDataPath)Customers_Master.qvd] (qvd);
DROP TABLE [Customers_Master];
//====================================================================
// GENERATE SALES TRANSACTIONS (2024 Data)
//====================================================================
[Sales_Transactions]:
LOAD
RowNo() as Transaction_ID,
Date(Date#('01-01-2024', 'DD-MM-YYYY') + Floor(Rand()*365)) as Transaction_Date,
Time(Floor(Rand()*86400)/86400, 'hh:mm:ss') as Transaction_Time,
Pick(Ceil(Rand()*3), 'Store', 'Online', 'Corporate') as Sales_Channel,
Pick(Ceil(Rand()*15),
'Store_N01', 'Store_N02', 'Store_N03',
'Store_S01', 'Store_S02', 'Store_S03',
'Store_E01', 'Store_E02', 'Store_E03',
'Store_W01', 'Store_W02', 'Store_W03',
'Store_C01', 'Store_C02', 'Store_C03') as Store_ID,
'P' & Text(Num(Ceil(Rand()*20), '000')) as Product_ID,
'C' & Text(Num(Ceil(Rand()*25), '0000')) as Customer_ID,
Ceil(Rand()*5) as Quantity,
Pick(Ceil(Rand()*10),
'EMP001', 'EMP002', 'EMP003', 'EMP004', 'EMP005',
'EMP006', 'EMP007', 'EMP008', 'EMP009', 'EMP010') as Sales_Rep_ID,
Pick(Ceil(Rand()*4), 'Cash', 'Credit Card', 'Debit Card', 'Digital Wallet') as Payment_Method,
If(Rand() > 0.95, 'Yes', 'No') as Is_Returned,
If(Rand() > 0.9, 'Yes', 'No') as Has_Warranty,
If(Rand() > 0.85, Ceil(Rand()*20), 0) as Discount_Percent
AUTOGENERATE 5000;
STORE [Sales_Transactions] INTO [$(vDataPath)Sales_Transactions.qvd] (qvd);
DROP TABLE [Sales_Transactions];
//====================================================================
// DATA GENERATION COMPLETE
//====================================================================
[Generation_Log]:
LOAD * INLINE [
File_Name, Records_Generated, Status
Products_Master.qvd, 20, Success
Customers_Master.qvd, 25, Success
Sales_Transactions.qvd, 5000, Success
] (delimiter is ',');
TRACE ====================================================================;
TRACE DATA GENERATION COMPLETED SUCCESSFULLY;
TRACE ====================================================================;
TRACE Location: C:\Practice\DataFiles\;
TRACE Files Created:;
TRACE - Products_Master.qvd (20 products);
TRACE - Customers_Master.qvd (25 customers);
TRACE - Sales_Transactions.qvd (5000 transactions);
TRACE ====================================================================;
TRACE Next Step: Create new app "TechRetail_Sales_Analysis" for exercises;
TRACE ====================================================================;
After running this script, verify:
✅ 3 QVD files exist in C:\Practice\DataFiles\
✅ File sizes are reasonable (not 0 KB)
✅ Generation Log shows "Success" for all files
Load the source QVD files and understand the data structure.
Instructions:
Business Requirements:
Expected Output:
[Products]:
LOAD
Product_ID,
Product_Name,
Category,
Sub_Category,
Brand,
Cost_Price,
Retail_Price,
// YOUR CODE HERE: Calculate Profit Margin %
// YOUR CODE HERE: Create Price Category
Reorder_Level,
// YOUR CODE HERE: Create Stock Status
Supplier_ID
FROM [C:\Practice\DataFiles\Products_Master.qvd] (qvd);
💡 Hint: Review Section 7.1 (IF Function) in the glossary for nested conditions.
Instructions:
Business Requirements:
Expected Output:
[Customers]:
LOAD
Customer_ID,
Customer_Name,
Customer_Type,
Region,
City,
State,
DATE(Date#(Join_Date, 'DD-MM-YYYY'), 'DD-MM-YYYY') as Join_Date,
// YOUR CODE HERE: Calculate Customer Age Days
// YOUR CODE HERE: Create Customer Segment
// YOUR CODE HERE: Extract Region Code
// YOUR CODE HERE: Create Is_Active_Customer flag
Email,
Phone,
Loyalty_Tier
FROM [C:\Practice\DataFiles\Customers_Master.qvd] (qvd);
💡 Hint:
Instructions:
Expected Output:
[Sales_Raw]:
LOAD
Transaction_ID,
DATE(Transaction_Date, 'DD-MM-YYYY') as Transaction_Date,
Transaction_Time,
Sales_Channel,
Store_ID,
Product_ID,
Customer_ID,
Quantity,
Sales_Rep_ID,
Payment_Method,
Is_Returned,
Has_Warranty,
Discount_Percent
FROM [C:\Practice\DataFiles\Sales_Transactions.qvd] (qvd);
Instructions:
Business Requirements: Create mappings for:
Expected Output:
//--- Product Mappings ---
[Map_Product_RetailPrice]:
MAPPING LOAD
Product_ID,
Retail_Price
RESIDENT Products;
[Map_Product_CostPrice]:
// YOUR CODE HERE
[Map_Product_Name]:
// YOUR CODE HERE
// Continue for all required mappings...
💡 Hint: Review Section 1.2 (MAPPING LOAD) and Section 8.1 (APPLYMAP) in glossary.
Transform raw sales data with business logic and create fact table.
Instructions:
Business Requirements:
Expected Output:
[Sales_Enriched]:
LOAD
Transaction_ID,
Transaction_Date,
Transaction_Time,
Sales_Channel,
Store_ID,
Product_ID,
APPLYMAP('Map_Product_Name', Product_ID, 'Unknown') as Product_Name,
// YOUR CODE HERE: Add other product fields via APPLYMAP
Customer_ID,
Quantity,
// YOUR CODE HERE: Calculate all amounts
Sales_Rep_ID,
Payment_Method,
Is_Returned,
Has_Warranty,
Discount_Percent
RESIDENT Sales_Raw;
DROP TABLE Sales_Raw;
💡 Hint: Review Section 8.1 (APPLYMAP) for lookups.
Instructions: Continue enriching Sales_Enriched table with customer data.
Business Requirements:
Expected Output:
LEFT JOIN (Sales_Enriched)
LOAD
Customer_ID,
Customer_Type,
Region,
Loyalty_Tier,
Customer_Segment
RESIDENT Customers;
// Then add Customer_Channel as calculated field
// YOUR CODE HERE
💡 Hint: Review Section 2.1 (LEFT JOIN).
Instructions:
Business Requirements: Create calendar with following fields:
Expected Output:
[Calendar]:
LOAD
TempDate as Date,
Year(TempDate) as Year,
Month(TempDate) as Month,
// YOUR CODE HERE: Add all other date fields
LOAD
Date(MinDate + IterNo() - 1) as TempDate
WHILE MinDate + IterNo() - 1 <= MaxDate;
LOAD
Min(Transaction_Date) as MinDate,
Max(Transaction_Date) as MaxDate
RESIDENT Sales_Enriched;
💡 Hint:
Instructions:
Business Requirements:
A. Daily Sales Summary:
[Daily_Sales_Summary]:
LOAD
Transaction_Date,
Region,
Sales_Channel,
Category,
COUNT(DISTINCT Transaction_ID) as Transaction_Count,
SUM(Quantity) as Total_Quantity,
SUM(Gross_Amount) as Total_Gross,
SUM(Discount_Amount) as Total_Discount,
SUM(Net_Amount) as Total_Net,
SUM(Profit_Amount) as Total_Profit,
// YOUR CODE HERE: Add AVG calculations
COUNT(DISTINCT Customer_ID) as Unique_Customers
RESIDENT Sales_Enriched
GROUP BY Transaction_Date, Region, Sales_Channel, Category;
B. Product Performance Summary:
[Product_Performance]:
LOAD
Product_ID,
Product_Name,
Category,
// YOUR CODE HERE: Aggregate by product
RESIDENT Sales_Enriched
GROUP BY Product_ID, Product_Name, Category;
C. Customer Purchase Summary:
[Customer_Summary]:
// YOUR CODE HERE: Create customer-level aggregations
// Include: Total purchases, Total amount spent, Avg transaction value, Last purchase date
💡 Hint: Review Section 3.2 (GROUP BY) and Section 9 (all aggregation functions).
Instructions: Create a separate returns analysis table.
Business Requirements:
Expected Output:
[Returns_Analysis]:
LOAD
Product_ID,
Product_Name,
Category,
COUNT(Transaction_ID) as Return_Count,
SUM(Net_Amount) as Return_Amount,
// YOUR CODE HERE: Add more calculations
RESIDENT Sales_Enriched
WHERE Is_Returned = 'Yes'
GROUP BY Product_ID, Product_Name, Category;
Instructions: Create top/bottom product rankings.
Business Requirements:
Expected Output:
[Top_Products_By_Revenue]:
LOAD
*,
RowNo() as Revenue_Rank
;
LOAD
Product_ID,
Product_Name,
SUM(Net_Amount) as Total_Revenue
RESIDENT Sales_Enriched
GROUP BY Product_ID, Product_Name
ORDER BY SUM(Net_Amount) DESC;
// YOUR CODE HERE: Create other ranking tables
💡 Hint: Review Section 10.3 (ROWNO) and Section 3.3 (ORDER BY).
Instructions: Save all transformed tables to QVD for future use.
Business Requirements:
Store the following tables as QVD in C:\Practice\DataFiles\Transformed\:
Expected Output:
LET vTransformedPath = 'C:\Practice\DataFiles\Transformed\';
STORE Sales_Enriched INTO [$(vTransformedPath)Sales_Enriched.qvd] (qvd);
STORE Daily_Sales_Summary INTO [$(vTransformedPath)Daily_Sales_Summary.qvd] (qvd);
// YOUR CODE HERE: Store remaining tables
💡 Hint: Review Section 15.3 (STORE).
Create complex business metrics and KPIs.
Instructions: Add previous month sales comparison to Daily_Sales_Summary.
Business Requirements: For each date, calculate:
Expected Output:
// Use PEEK or mapping approach
// YOUR CODE HERE
// Alternative: Calculate in chart expressions using Set Analysis
💡 Hint: Review Section 10.1 (PEEK) or use Set Analysis from Section 13.
Instructions: Calculate RFM (Recency, Frequency, Monetary) score for customers.
Business Requirements: For each customer:
Expected Output:
[Customer_RFM]:
LOAD
Customer_ID,
Customer_Name,
// YOUR CODE HERE: Calculate days since last purchase
// YOUR CODE HERE: Calculate frequency score
// YOUR CODE HERE: Calculate monetary score
// YOUR CODE HERE: Create RFM_Score
RESIDENT Sales_Enriched;
💡 Hint: Use nested IF statements (Section 7.1) and TODAY() function (Section 5.4).
Instructions: Calculate how fast products are selling.
Business Requirements: For each product:
Expected Output:
[Product_Velocity]:
LOAD
Product_ID,
Product_Name,
// YOUR CODE HERE
RESIDENT Sales_Enriched
GROUP BY Product_ID, Product_Name;
💡 Hint: Use MIN/MAX dates (Section 9.3) to calculate days on market.
Instructions: Identify products that might benefit from price adjustment.
Business Requirements: Flag products for price review if:
Create Price_Review_Reason field explaining why.
Expected Output:
[Price_Optimization]:
LOAD
*,
If(// YOUR CONDITIONS HERE, 'Yes', 'No') as Needs_Price_Review,
// YOUR CODE HERE: Add reason
RESIDENT Product_Performance;
Create a comprehensive dashboard to answer business questions.
Create 4 sheets in QlikSense with the following visualizations:
KPI Tiles (Top of page):
Total Revenue (current year)
Sum(Net_Amount)Total Profit
Sum(Profit_Amount)Profit Margin %
Sum(Profit_Amount) / Sum(Net_Amount)Total Transactions
Count(DISTINCT Transaction_ID)Avg Transaction Value
Avg(Net_Amount)Chart 1: Monthly Revenue Trend
Sum(Net_Amount)Sum(Profit_Amount)Chart 2: Revenue by Region (Pie Chart)
Sum(Net_Amount)Chart 3: Revenue by Sales Channel (Bar Chart)
Chart 4: Top 10 Products by Revenue (Bar Chart)
Sum(Net_Amount)Chart 1: Category Performance (Combo Chart)
Sum(Net_Amount)Sum(Profit_Amount) / Sum(Net_Amount)Chart 2: Product Performance Matrix (Scatter Plot)
Chart 3: Price Category Distribution (Treemap)
Chart 4: Sales Velocity Analysis (Table)
Filter Pane:
Chart 1: Customer Segmentation (Stacked Bar)
Count(DISTINCT Customer_ID)Sum(Net_Amount)Chart 2: RFM Distribution (Heatmap / Pivot Table)
Chart 3: Customer Lifetime Value (Bar Chart)
Chart 4: Loyalty Tier Performance
Chart 5: Region-wise Customer Distribution (Map or Bar)
Filter Pane:
KPI Tiles:
Total Returns
Count({<Is_Returned={'Yes'}>} Transaction_ID)Return Rate %
Count({<Is_Returned={'Yes'}>} Transaction_ID) / Count(Transaction_ID)Return Amount
Sum({<Is_Returned={'Yes'}>} Net_Amount)Chart 1: Returns by Category (Bar Chart)
Chart 2: Returns Trend (Line Chart)
Chart 3: Top Products by Returns (Table)
Chart 4: Returns by Reason Matrix
Filter Pane:
Profit Margin % Calculation:
((Retail_Price - Cost_Price) / Retail_Price) * 100 as Profit_Margin_Pct
Price Category (Nested IF):
If(Retail_Price < 50, 'Budget',
If(Retail_Price <= 500, 'Mid-Range',
If(Retail_Price <= 1000, 'Premium', 'Luxury')
)
) as Price_Category
Stock Status:
If(Reorder_Level < 50, 'Critical',
If(Reorder_Level <= 100, 'Low',
If(Reorder_Level <= 200, 'Normal', 'High')
)
) as Stock_Status
Customer Age Days:
Today() - Date#(Join_Date, 'DD-MM-YYYY') as Customer_Age_Days
Customer Segment (Complex Nested IF):
If(Customer_Type = 'Corporate',
If(Loyalty_Tier = 'Platinum', 'VIP Corporate',
If(Loyalty_Tier = 'Gold', 'Key Corporate', 'Regular Corporate')
),
If(Match(Loyalty_Tier, 'Platinum', 'Gold'), 'Premium Individual', 'Standard Individual')
) as Customer_Segment
Region Code:
LEFT(Region, 1) as Region_Code
Is_Active_Customer:
If(Today() - Date#(Join_Date, 'DD-MM-YYYY') <= 180, 'Yes', 'No') as Is_Active_Customer
All Mapping Tables:
[Map_Product_RetailPrice]:
MAPPING LOAD Product_ID, Retail_Price RESIDENT Products;
[Map_Product_CostPrice]:
MAPPING LOAD Product_ID, Cost_Price RESIDENT Products;
[Map_Product_Name]:
MAPPING LOAD Product_ID, Product_Name RESIDENT Products;
[Map_Product_Category]:
MAPPING LOAD Product_ID, Category RESIDENT Products;
[Map_Customer_Type]:
MAPPING LOAD Customer_ID, Customer_Type RESIDENT Customers;
[Map_Customer_Region]:
MAPPING LOAD Customer_ID, Region RESIDENT Customers;
Sales Amount Calculations:
Quantity * APPLYMAP('Map_Product_RetailPrice', Product_ID, 0) as Gross_Amount,
Gross_Amount * (Discount_Percent / 100) as Discount_Amount,
Gross_Amount - Discount_Amount as Net_Amount,
Quantity * APPLYMAP('Map_Product_CostPrice', Product_ID, 0) as Cost_Amount,
Net_Amount - Cost_Amount as Profit_Amount,
(Profit_Amount / Net_Amount) * 100 as Profit_Margin_Pct
Note: You may need to use preceding load pattern:
[Sales_Enriched]:
LOAD *,
Gross_Amount - Discount_Amount as Net_Amount,
Net_Amount - Cost_Amount as Profit_Amount
;
LOAD
*,
Quantity * Retail_Price as Gross_Amount,
Gross_Amount * (Discount_Percent / 100) as Discount_Amount,
Quantity * Cost_Price as Cost_Amount
;
LOAD
Transaction_ID,
// ... other fields
APPLYMAP('Map_Product_RetailPrice', Product_ID, 0) as Retail_Price,
APPLYMAP('Map_Product_CostPrice', Product_ID, 0) as Cost_Price
RESIDENT Sales_Raw;
Calendar Creation - Complete Solution:
[Calendar]:
LOAD
TempDate as Date,
Year(TempDate) as Year,
Month(TempDate) as Month,
Dual(
Text(Month(TempDate)) & ' - ' & Text(Year(TempDate)),
Year(TempDate) & Num(Month(TempDate), '00')
) as Month_Name,
'Q' & Ceil(Month(TempDate)/3) as Quarter,
Year(TempDate) & '-' & Num(Month(TempDate), '00') as Year_Month,
Year(TempDate) & '-Q' & Ceil(Month(TempDate)/3) as Year_Quarter,
Week(TempDate) as Week_Number,
WeekDay(TempDate) as Day_of_Week,
If(WeekDay(TempDate) >= 5, 'Yes', 'No') as Is_Weekend,
'Q' & Ceil((Month(AddMonths(TempDate, -3))/3)) as Fiscal_Quarter
;
LOAD
Date(MinDate + IterNo() - 1) as TempDate
WHILE MinDate + IterNo() - 1 <= MaxDate;
LOAD
Min(Transaction_Date) as MinDate,
Max(Transaction_Date) as MaxDate
RESIDENT Sales_Enriched;
RFM Score Calculation:
[Customer_RFM]:
LOAD
Customer_ID,
Max(Transaction_Date) as Last_Purchase_Date,
Today() - Max(Transaction_Date) as Days_Since_Last_Purchase,
If(Today() - Max(Transaction_Date) < 30, 5,
If(Today() - Max(Transaction_Date) <= 60, 4,
If(Today() - Max(Transaction_Date) <= 90, 3,
If(Today() - Max(Transaction_Date) <= 180, 2, 1)
)
)
) as Recency_Score,
Count(Transaction_ID) as Transaction_Count,
If(Count(Transaction_ID) > 20, 5,
If(Count(Transaction_ID) >= 16, 4,
If(Count(Transaction_ID) >= 11, 3,
If(Count(Transaction_ID) >= 6, 2, 1)
)
)
) as Frequency_Score,
Sum(Net_Amount) as Total_Spending,
If(Sum(Net_Amount) > 5000, 5,
If(Sum(Net_Amount) > 2000, 4,
If(Sum(Net_Amount) > 1000, 3,
If(Sum(Net_Amount) > 500, 2, 1)
)
)
) as Monetary_Score
RESIDENT Sales_Enriched
GROUP BY Customer_ID;
// Add concatenated RFM score
LEFT JOIN (Customer_RFM)
LOAD
Customer_ID,
Text(Recency_Score) & Text(Frequency_Score) & Text(Monetary_Score) as RFM_Score
RESIDENT Customer_RFM;
Script Tabs (Minimum 7 tabs):
Transformed QVD Files (6 files):
Dashboard Sheets (4 sheets):