2009-07-16 124 views
1

這可能看起來有點像我的家庭作業問題(而且是),但我認爲我試圖獲得的銷售結果是相當通用的,並且會對於進行銷售報告的任何人都有用在SQL中的LFL銷售查詢

我有一個基本的銷售表(字段:DateOfSaleSalesAmount兩個)在SQL Server 2005中,我需要建立與該表中的數據的報告。我在SQL之後會爲我提供該報告的數據。

實際的表使用了BranchID,我在這個例子中改變了Branch。

安裝腳本

-- 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) 

假設

  1. 一週的第一天是星期一
  2. 今天的日期是星期三,2009年

16年7月1日類似對等的銷售:從昨天

DailyLFL 名所需的結果

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 

每日銷售 銷售。所以,1年前的這一天的銷售。不是在7月15日的這一天,而是第29周的星期三(即7月16日)。如果此分行不到一年(如開普敦分行),則使用上週的銷售額(即上週三)。如果上週沒有銷售,那麼爲零。

WTD:本週至今。銷售額從本週一開始到昨天結束。所以,在我的例子中,星期一,星期二,星期三。

WTD LFL: 本週至今喜歡的。相同的邏輯LF​​L,但這次WTD代替每日銷售

LFL: 某個位標誌顯示,如果我們能夠使用LFL(價值:1),或者不得不使用最後一個星期的銷售(價值: 0)

由於這些是零售銷售的標準指標,我希望有人已經爲他們編寫了SQL。也許不是上一年即將使用的最後一週,但肯定是LFL和WTD。

如果解決方案需要日曆表(例如http://tinyurl.com/nt5gck),那很好。

回答

1

我沒有很好的答案,所以我不得不自己做這個。爲了完整起見,這是我的答案。

請注意,答案在我的數據庫使用真正的表名(Sales_ByDay:ProfitCentreID,DateOfSale,NetSalesAmt),而不是由表我在我的問題提到(銷售:分公司,DateOfSale,SalesAmount兩個)

功能:Alerts_DailySales

create function Alerts_DailySales 
(
@StartDate smalldatetime, 
@EndDate smalldatetime 
) 
returns table 
as 
return 
(
select 
r.ProfitCentreID, 
s.DateOfSale, 
sum(s.NetSalesAmt) DailySales 
from Sales_ByDay s 
inner join RevenueCentres r on s.RevenueCentreID = r.RevenueCentreID 
where s.DateOfSale >= @StartDate 
and s.DateOfSale <= @EndDate 
group by r.ProfitCentreID, s.DateOfSale 
) 

功能:Alerts_WTDSales

create function Alerts_WTDSales 
(
@StartDate smalldatetime, 
@EndDate smalldatetime 
) 
returns table 
as 
return 
(
select 
a.ProfitCentreID, 
a.DateOfSale, 
max(a.DailySales) DailySales, 
sum (b.DailySales) WTDSales 
from dbo.Alerts_DailySales(@StartDate, @EndDate) a 
left outer join dbo.Alerts_DailySales(@StartDate, @EndDate) b on a.ProfitCentreID = b.ProfitCentreID and a.DateOfSale >= b.DateOfSale 
group by a.ProfitCentreID, a.DateOfSale 
) 

功能:Date_GetMonday

create function [dbo].[Date_GetMonday] (@dt smalldatetime) 
returns smalldatetime 
as 
begin 
    return dateadd(week, datediff(week, 0, @dt-1), 0) 
end 

PROC:Alerts_SalesReport

create proc Alerts_SalesReport 
as 

set nocount on 

declare @StartDate_CW smalldatetime 
declare @EndDate_CW smalldatetime 
declare @StartDate_LW smalldatetime 
declare @EndDate_LW smalldatetime 
declare @StartDate_LY smalldatetime 
declare @EndDate_LY smalldatetime  

-- sort out dates 
set @EndDate_CW = dateadd(day, -1, Util.dbo.Date_RoundToDay(getdate())) -- yesterday 
set @StartDate_CW = Util.dbo.Date_GetMonday(@EndDate_CW) 
set @StartDate_LW = dateadd(day, -7, @StartDate_CW) 
set @EndDate_LW = dateadd(day, -7, @EndDate_CW) 
set @StartDate_LY = dateadd(week, -52, @StartDate_CW) 
set @EndDate_LY = dateadd(week, -52, @EndDate_CW) 

-- get sales 
select 
ProfitCentreName Branch, 
cw.DailySales, 
coalesce(ly.DailySales, lw.DailySales, 0) DailyLFL, 
cw.DailySales - coalesce(ly.DailySales, lw.DailySales, 0) DailyVar, 
cw.WTDSales, 
coalesce(ly.WTDSales, lw.WTDSales, 0) WTD_LFL, 
cw.WTDSales - coalesce(ly.WTDSales, lw.WTDSales, 0) WTDVar, 
cast(isnull(ly.DailySales, 0) as bit) LFL 
from ProfitCentreNames pn 
inner join dbo.Alerts_WTDSales(@StartDate_CW, @EndDate_CW) cw on pn.ProfitCentreID = cw.ProfitCentreID 
left outer join dbo.Alerts_WTDSales(@StartDate_LW, @EndDate_LW) lw on cw.ProfitCentreID = lw.ProfitCentreID and dateadd(day, -7, cw.DateOfSale) = lw.DateOfSale 
left outer join dbo.Alerts_WTDSales(@StartDate_LY, @EndDate_LY) ly on cw.ProfitCentreID = ly.ProfitCentreID and dateadd(week, -52, cw.DateOfSale) = ly.DateOfSale 
where cw.DateOfSale = @EndDate_CW 
order by pn.ProfitCentreName, cw.DateOfSale 

我不知道這是否會工作馬上,如果你只是複製和粘貼,但你應該能夠接受邏輯。

+0

在作業問題上,你自己回答它們通常是有意義的。現在你的大腦已經形成了更多的皺紋,或者如果你過去玩過角色扮演遊戲,就會獲得一個新的水平。 /播放誇耀/ – 2009-07-27 13:33:29