This might seem a bit like a do-my-homework-for-me question (and it is), but I think that the sales results I’m trying to get are fairly generic and will be useful for anyone doing sales reporting.
I have a basic Sales table (fields: Branch, DateOfSale, SalesAmount) in SQL Server 2005 and I need to build a report with the data in that table. I'm after the SQL that will give me the data for that report.
The actual table used BranchID, which I have changed to Branch in this example.
SetUp Script
-- create sales table
CREATE TABLE Sales(
Branch varchar(30) NOT NULL,
DateOfSale smalldatetime NOT NULL,
SalesAmount money NOT NULL)
-- London: same week last year
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090714',100)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090715',200)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090716',300)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090717',400)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090718',500)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090719',600)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090720',700)
-- London: last 2 weeks sales
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090706',1000)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090707',1100)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090708',1200)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090709',1300)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090710',1400)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090711',1500)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090712',1600)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090713',1700)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090714',1800)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('London','20090715',1900)
-- Cape Town: last 2 weeks sales
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090706',2000)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090707',2100)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090708',2200)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090709',2300)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090710',2400)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090711',2500)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090712',2600)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090713',2700)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090714',2800)
INSERT INTO Sales (Branch, DateOfSale, SalesAmount) VALUES ('Cape Town','20090715',2900)
Assumptions
- The first day of the week is Monday
- Today’s date is Wed, 16 July 2009
Required Result
Branch DailySales DailyLFL WTD WTDLFL LFL
London 1900.00 300.00 5400.00 600.00 Y
Cape Town 2900.00 2200.00 8400.00 6300.00
Daily Sales Sales from yesterday
DailyLFL: Like-for-like sales. So, sales for this day 1 year ago. Not this day as in 15 July, but rather Wed of the 29th week (which is 16 July). If this branch is less than a year old (like the Cape Town branch), then use last weeks sales (i.e. Wed last week). If no sales last week, then zero.
WTD: Week-to-date. Sales summed starting at Monday this week until yesterday. So, Mon, Tues, Wed in my example.
WTD LFL: Week-to-date like-for-like. The same logic as LFL, but this time with WTD instead of Daily Sales
LFL: A bit flag show if we were able to use LFL (value: 1) or had to use last weeks sales (value: 0)
As these are standard metrics in retail sales, I’m hoping that someone has already written the SQL for them. Maybe not the if-you-do-not-have-last-year-then-use-last-week bit, but definitely LFL and WTD.
If the solution needs a calendar table (e.g. http://tinyurl.com/nt5gck), that's fine.