13. DAX: Data Analysis Expressions
13.5 Base Measures for the Quick-Commerce Model
Create these first; later measures reuse them. Reusing measures ("measure branching") keeps your model consistent and easy to maintain. Remember the grain (एका ओळीचा नेमका अर्थ) from Module 1.7: one row per order line, and cancelled orders have Amount = 0.
Total Sales = SUM(Orders[Amount]) -- net value after discount
Total Orders = DISTINCTCOUNT(Orders[Order ID])
Delivered Orders = CALCULATE([Total Orders], Orders[Order Status] = "Delivered")
Cancelled Orders = CALCULATE([Total Orders], Orders[Order Status] = "Cancelled")
Total Quantity = SUM(Orders[Quantity])
Total Discount = SUM(Orders[Discount])
Active Customers = DISTINCTCOUNT(Orders[Customer ID])
Format Total Sales and Total Discount as currency (₹) and ratio measures as percentage in Measure tools › Format.
Quick-commerce KPIs
AOV (Average Order Value) = DIVIDE([Total Sales], [Delivered Orders])
Cancellation Rate = DIVIDE([Cancelled Orders], [Total Orders])
-- Delivery time is an order-level value repeated on every line,
-- so first take one value per order, then average across orders
Avg Delivery Time (mins) =
AVERAGEX(
VALUES(Orders[Order ID]),
CALCULATE(MAX(Orders[Delivery Time Mins]))
)
% Orders Delivered Under 10 Mins =
DIVIDE(
CALCULATE([Delivered Orders], Orders[Delivery Time Mins] <= 10),
[Delivered Orders]
)
Orders per Dark Store =
DIVIDE([Total Orders], DISTINCTCOUNT(Orders[Store ID]))
Repeat Customer % =
DIVIDE(
COUNTROWS(FILTER(VALUES(Customer[Customer ID]), [Total Orders] > 1)),
[Active Customers]
)
Delivery Fee Revenue =
SUMX(
VALUES(Orders[Order ID]),
CALCULATE(MAX(Orders[Delivery Fee]))
)
Cost of Goods Sold =
CALCULATE(
SUMX(Orders, Orders[Quantity] * RELATED(Product[Unit Cost])),
Orders[Order Status] = "Delivered"
)
Gross Profit = [Total Sales] - [Cost of Goods Sold]
Gross Margin % = DIVIDE([Gross Profit], [Total Sales])
Why not simply AVERAGE(Orders[Delivery Time Mins])?
An order with five lines would be counted five times and a one-line order once, so big orders would pull the average. AVERAGEX(VALUES(Orders[Order ID]), …) gives each order equal weight. Cancelled orders have a blank delivery time, and AVERAGEX ignores blanks. Always check the grain of your data before choosing an aggregation.
"Under 10 mins" here means 10 minutes or less (<= 10). Agree on the exact definition of every KPI with the business before building it.
Aata pudhe jaauya aggregation functions kade. Pan aadhi he base measures tumchya file madhe banvun theva.
Ravindra Bagale's Tip
Friends, many students average the Delivery Time column directly, so big orders with many lines count several times. Check the grain before choosing an aggregation: here, take one value per order with AVERAGEX(VALUES(Orders[Order ID]), …). Agree every KPI definition (for example "under 10 minutes means ≤ 10") with the business. Don't make this mistake!
Ravindra Bagale's Tip – मराठी
मित्रांनो, बरेच students Delivery Time column चं थेट average घेतात, त्यामुळे अनेक lines असलेल्या मोठ्या orders अनेकदा मोजल्या जातात. Aggregation निवडण्याआधी grain तपासा: इथे AVERAGEX(VALUES(Orders[Order ID]), …) ने प्रत्येक order ची एकच value घ्या. प्रत्येक KPI ची व्याख्या (उदाहरणार्थ "under 10 minutes म्हणजे ≤ 10") business सोबत ठरवून घ्या. ही चूक करू नका!
Ravindra Bagale's Tip – हिंदी
दोस्तों, बहुत से students Delivery Time column का सीधा average ले लेते हैं, जिससे कई lines वाले बड़े orders कई बार गिने जाते हैं. Aggregation चुनने से पहले grain check करो: यहाँ AVERAGEX(VALUES(Orders[Order ID]), …) से हर order की एक ही value लो. हर KPI की परिभाषा (जैसे "under 10 minutes यानी ≤ 10") business के साथ तय कर लो. यह गलती मत करना!