2009-07-16 85 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