Retail sales per sq ft and like-for-like growth, calculated properly
In this article (6 sections)
Related programme: the Data Analytics with Generative AI course (3–4 months; ₹90,000 (inclusive of GST) · EMI from ₹4,000/month).
Sales per square foot is net sales for a period divided by the store's selling area, and like-for-like (LFL) growth is the sales growth of only those stores that traded normally in both the current and the comparison period. The arithmetic is trivial. Nearly all the work is in two decisions made before any query runs: which area figure goes in the denominator, and which stores count as "like".
A growth figure that flatters the chain
The retail head of a four-store chain sees August–September sales up 4.5% on last year and calls it a good season. The chain opened a store in Meerut in February 2025, so that store was still ramping up last year, and it closed its Agra store for six weeks of refurbishment this August. One store is inflating growth, another is deflating it, and the 4.5% mixes both with the two stores that simply traded. The LFL number for the two comparable stores is 4.0%, and one of those two is actually shrinking.
Deciding the denominators first
Which area? Leases in India commonly quote chargeable or super built-up area, which includes a share of common corridors, lifts and walls. Operations should use carpet or selling area — the floor customers can walk and product can sit on. Stockrooms and trial rooms are a judgement call; whatever you choose, apply it to every store and write it in the footnote. Because chargeable area is always the larger figure, the same store looks less productive per square foot on a lease-based denominator than on a carpet-based one, so ask for the definition, not just the number.
Which period? Sales per sq ft is only comparable across stores over the same number of days. Report it per month (or annualised) and divide by the number of months in the window.
Which stores are "like"? A common rule is that a store enters the LFL base only after it has traded for a full twelve months before the start of the comparison period, and leaves it for any period affected by a closure, major refurbishment, relocation or a significant change in selling area. The exact rule differs between retailers. Pick one, apply it mechanically, and never re-decide it after seeing the results.
Sales density and the LFL growth formula
| KPI | Formula |
|---|---|
| Sales per sq ft per month | Net sales in window ÷ carpet sq ft ÷ months in window |
| Store growth % | (This-year sales − last-year sales) ÷ last-year sales × 100 |
| LFL growth % | (Σ TY sales − Σ LY sales) ÷ Σ LY sales × 100, over LFL stores only |
| Total growth % | Same, over all stores |
Note the LFL formula sums sales first, then divides. The mean of the store growth rates gives a small store the same weight as a flagship and is not LFL.
The query, on four synthetic stores
Net sales are in ₹ lakh. The eligibility date 2024-08-01 implements the twelve-months-before-last-year's-window rule for an August start.
CREATE TABLE stores (store_id TEXT, city TEXT, opened_on TEXT, carpet_sqft INT, closed_weeks_fy26 INT);
CREATE TABLE monthly_sales (store_id TEXT, month TEXT, net_sales REAL);
INSERT INTO stores VALUES
('S1','Noida', '2021-04-10', 4000, 0),
('S2','Ghaziabad','2022-11-01', 3200, 0),
('S3','Meerut', '2025-02-15', 2500, 0),
('S4','Agra', '2019-08-20', 3600, 6);
-- Net sales (Rs lakh) for Aug-Sep of last year and this year; synthetic
INSERT INTO monthly_sales VALUES
('S1','2025-08',40.0),('S1','2025-09',42.0),('S1','2026-08',43.0),('S1','2026-09',45.2),
('S2','2025-08',28.0),('S2','2025-09',29.0),('S2','2026-08',27.5),('S2','2026-09',28.9),
('S3','2025-08',12.0),('S3','2025-09',14.0),('S3','2026-08',21.0),('S3','2026-09',22.0),
('S4','2025-08',30.0),('S4','2025-09',31.0),('S4','2026-08',18.0),('S4','2026-09',30.5);
WITH per_store AS (
SELECT s.store_id, s.carpet_sqft, s.opened_on, s.closed_weeks_fy26,
SUM(CASE WHEN m.month LIKE '2025-%' THEN net_sales END) AS ly,
SUM(CASE WHEN m.month LIKE '2026-%' THEN net_sales END) AS ty
FROM stores s JOIN monthly_sales m USING (store_id)
GROUP BY s.store_id),
flagged AS (
SELECT *,
CASE WHEN opened_on > '2024-08-01' THEN 'new (not 12m trading at LY start)'
WHEN closed_weeks_fy26 > 0 THEN 'excluded: refurbishment closure'
ELSE 'LFL' END AS lfl_status
FROM per_store)
SELECT store_id, lfl_status,
ROUND(ty * 100000.0 / carpet_sqft / 2, 0) AS sales_per_sqft_month,
ROUND(100.0 * (ty - ly) / ly, 1) AS growth_pct
FROM flagged
UNION ALL
SELECT 'LFL total', '', NULL,
ROUND(100.0 * (SUM(ty) - SUM(ly)) / SUM(ly), 1) FROM flagged WHERE lfl_status = 'LFL'
UNION ALL
SELECT 'All-store total', '', NULL,
ROUND(100.0 * (SUM(ty) - SUM(ly)) / SUM(ly), 1) FROM flagged;| store_id | lfl_status | sales_per_sqft_month | growth_pct |
|---|---|---|---|
| S1 | LFL | 1103 | 7.6 |
| S2 | LFL | 881 | -1.1 |
| S3 | new (not 12m trading at LY start) | 860 | 65.4 |
| S4 | excluded: refurbishment closure | 674 | -20.5 |
| LFL total | 4.0 | ||
| All-store total | 4.5 |
Read the rows together. S3's 65.4% is a young store maturing, not a Meerut success story yet. S4's −20.5% is six closed weeks, not a failing Agra market — its September recovered almost to last year's level. With both removed, the chain's underlying growth is 4.0%, driven entirely by S1; S2 in Ghaziabad is down 1.1%. That last line is the finding worth a meeting, and the headline 4.5% buried it.
S4's sales density (₹674 per sq ft a month) is also distorted by the closure, since the area stayed in the denominator for weeks it could not trade. For density, either exclude closed days from the window or mark the store as not comparable, as the LFL flag does.
Other things that break comparability
Festival calendar shifts. Diwali, Durga Puja, Eid and regional harvest festivals move between months from year to year. A September-versus-September comparison can swing by double digits purely because the festival's pre-buying week moved into October. Compare festival-aligned windows (the same number of days before the festival) for seasonal categories, or at least annotate the report.
Different trading-day counts. One more weekend in this year's month changes the answer for footfall-driven formats. Compare same-weekday-aligned periods or report sales per trading day.
Area changes without a refurbishment. Converting a stockroom to selling space, adding a shop-in-shop concession, or giving floor to a brand partner changes the denominator. Keep a dated area history table rather than a single carpet_sqft column.
Returns and exchanges. Use net sales after returns. Large post-festival return weeks will otherwise make the festival month look stronger and the following month weaker.
Online orders fulfilled from store. Decide whether ship-from-store or buy-online-pick-up-in-store sales belong to the store. It matters most for sales per sq ft: an order fulfilled from the stockroom never used the selling floor.
Showing the result to a retail head
Lead with LFL and total growth side by side, and a one-line bridge between them: "Total +4.5%; LFL +4.0%; the new Meerut store added growth, the Agra refurbishment took it away." Then show the LFL stores ranked by growth with sales density beside it, because a store that is shrinking and has low density is a different problem (location or range) from one shrinking at high density (possibly capacity or staffing at peak hours). Keep the non-LFL stores in a separate block with their reason, so nobody asks why Meerut is "missing".
Retail MIS like this is where many store-operations people start their move into analytics; retail store manager to retail data analyst covers that route. SQL with CTEs, conditional aggregation and cohort flags is taught throughout the Data Analyst programme.
Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.
This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.
Explore Data Analytics with Generative AI