获取SQL中每行的销售额之间的平均月数

时间:2015-03-28 18:38:41

标签: sql-server sql-server-2008 tsql

Name         Customer   StockCode       Description         3/01/2013   4/01/2013   5/01/2013   6/01/2013   7/01/2013   8/01/2013   9/01/2013   10/01/2013  11/01/2013  12/01/2013  1/01/2014   2/01/2014   3/01/2014   4/01/2014   5/01/2014   6/01/2014   7/01/2014   8/01/2014   9/01/2014   10/01/2014  11/01/2014  12/01/2014  1/01/2015   2/01/2015   3/01/2015
AAG Ice Cream   564     243702  4/1 Gal Ja-Rtu Pineapple    NULL    NULL    NULL    274.40  NULL    NULL    313.60  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    392.00  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
AAG Ice Cream   564     243701  4/1 Gal Ja-Rtu Strawberry   NULL    NULL    NULL    660.00  NULL    NULL    NULL    660.00  NULL    NULL    NULL    NULL    NULL    NULL    NULL    660.00  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
AAG Ice Cream   564     248050  4/1 Gal-RTU Choc Syrup      NULL    NULL    NULL    534.00  NULL    NULL    534.00  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    534.00  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL

我需要确定每行销售额之间的平均月数。因此,如果我有3个零,那么一个销售然后4个零,然后一个销售,然后4个零和一个销售连续我可以得出3.6个月(4个圆形)平均该客户在过去24个期间购买一个项目如果我从今天开始看到5个月没有销售,我可以在那一行标记客户。(客户/ StockCode组合。)

其他样式 - 直接查询无枢轴。

SELECT Customer,StockCode,SUM(InvoiceValue) as Amount ,MONTH(TrnDate) as        [Month],YEAR(TrnDate) as [Year]
 FROM ArSalesMove
  WHERE TrnDate BETWEEN  DATEADD(YEAR,-2,GetDate())   AND  GETDATE()
  GROUP BY Customer,StockCode,MONTH(TrnDate),YEAR(TrnDate)
  ORDER BY Customer,StockCode,YEAR(TrnDate),MONTH(TrnDate)
Customer StockCode      Amount  Month   Year
0000023 850802          3542.40  5  2013
0000023 850802          0        6  2013
0000023 850802          0        7  2013
0000023 850802          0        8  2013
0000023 850802          2361.60  9  2013
0000023 850802          0        10 2013
0000023 850802          0        11 2013
0000023 850802          0        12 2013
0000023 850802          2361.60   1 2014
0000023 850802          0         2 2014
0000023 850802          0         3 2014
0000023 850802          0         4 2014
0000023 850802          4723.20   5 2014
0000023 850802          0         6 2014
0000023 850802          0         7 2014
0000023 850802          3542.40   8 2014
0000023 850802          0         9 2014
0000023 850802          0        10 2014
0000023 850802          0        11 2014
0000023 850802          2361.60  12 2014
0000023 850802          0         1 2015
0000023 850802          0         2 2015
0000023 850802          0         3 2015
CREATE TABLE [dbo].[ArSalesMove](
[Customer] [char](7) NOT NULL,
[TrnDate] [datetime] NOT NULL,
[Register] [decimal](5, 0) NOT NULL,
[SummaryLine] [decimal](5, 0) NOT NULL,
[DetailLine] [decimal](5, 0) NOT NULL,
[Invoice] [char](6) NULL,
[StockCode] [char](30) NULL,
[Warehouse] [char](2) NULL,
[InvoiceQty] [decimal](10, 3) NULL,
[InvoiceValue] [decimal](14, 2) NULL,
[CostValue] [decimal](14, 2) NULL,
[DocumentType] [char](1) NULL,
[Branch] [char](2) NULL,
[Salesperson] [char](3) NULL,
[Bin] [char](6) NULL,
[OrderType] [char](2) NULL,
[Area] [char](2) NULL,
[ProductClass] [char](4) NULL,
[TaxCode] [char](1) NULL,
[TaxValue] [decimal](14, 2) NULL,
[DiscValue] [decimal](14, 2) NULL,
[TaxCodeFst] [char](1) NULL,
[TaxValueFst] [decimal](14, 2) NULL,
[SalesOrder] [char](6) NULL,
[CustomerPoNumber] [char](30) NULL,
[TrnYear] [decimal](4, 0) NULL,
[TrnMonth] [decimal](2, 0) NULL,
[ForInvoiceValue] [decimal](14, 2) NULL,
[InvoiceCurrency] [char](3) NULL,
[SalesOrderLine] [decimal](4, 0) NULL,
[TimeStamp] [timestamp] NULL,
CONSTRAINT [ArSalesMoveKey] PRIMARY KEY CLUSTERED 
(
  [Customer] ASC,
  [TrnDate] ASC,
  [Register] ASC,
  [SummaryLine] ASC,
  [DetailLine] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,     ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

1 个答案:

答案 0 :(得分:0)

我所做的是创建一个GroupID字段,然后我用一个值填充它,其中InvoiceValue不等于0:

 SET @counter = 0
 UPDATE @tempSales 
 SET @counter = tt.GroupID = @counter + 1
 FROM @tempSales  tt
 WHERE  CASE WHEN tt.InvoiceValue <> 0 THEN 1 ELSE 0 END = 1

这给我留下了NULL值,其中InvoiceValue为NULL,所以我回填了Null:

 SELECT t1.ID,t1.TrnDate, t1.Customer,t1.StockCode,t1.InvoiceValue,
(--Fill Back null Values...
SELECT t2.GroupID
FROM @tempSales t2
WHERE t2.ID = (
    SELECT MAX(t3.ID)
    FROM @tempSales t3
    WHERE t3.ID <= t1.ID
    AND GroupID IS NOT NULL
   )
 ) AS GroupID
FROM @tempSales t1   

下一步我计算了GroupID和Group BY GroupID。

然后我得到了平均值的计数,然后是最后一次销售日期MAX(TrnDate),并为Customer / StockCode组合创建了一个超过销售之间平均月份的标志。

  CASE WHEN MonthsSinceLastSale > ZeroAvg + 1 THEN 1 ELSE 0 END as Flag -

这就是存储过程......

ALTER PROC GetZeroMonthsReport
@Customer Varchar(50),
@StockCode Varchar(50)

as

DECLARE @tempSales TABLE (ID INT IDENTITY (1,1) NOT NULL PRIMARY KEY,    TrnDate DATETIME, Customer NVARCHAR(50),StockCode NVARCHAR(50), InvoiceValue      decimal, GroupID INT)
DECLARE @temp  TABLE (ID INT IDENTITY (1,1) NOT NULL PRIMARY KEY, TrnDate   DATETIME, Customer NVARCHAR(50),StockCode NVARCHAR(50), InvoiceValue decimal,   GroupID INT)
DECLARE @counter int


INSERT INTO @temp (TrnDate, Customer,StockCode, InvoiceValue)
Select  CONVERT(VARCHAR(50),MONTH(TrnDate)) + '/01/' +   CONVERT(VARCHAR(50),Year(TrnDate)) as TrnDate ,  RTRIM(Customer),RTRIM(StockCode), SUM(InvoiceValue)
FROM dbo.ArSalesMove s WITH(NOLOCK)
WHERE TrnDate BETWEEN  DATEADD(YEAR,-2,GetDate())   AND  GETDATE()
AND RTRIM(Customer)+RTRIM(StockCode) NOT IN ( SELECT   RTRIM(Customer)+RTRIM(StockCode) FROM dbo.ArSalesExclusion a WITH(NOLOCK))
 AND RTRIM(Customer)<>'999'
 AND RTRIM(StockCode)<>'704033'--Wood Pallets    
 AND RTRIM(Customer)IN (SELECT DISTINCT  RTRIM(Customer) From ArSalesMove   WHERE TrnDate Between DATEADD(YEAR,-2,GetDate())   AND  GETDATE())
 AND RTRIM(StockCode)IN (SELECT DISTINCT  RTRIM(StockCode) From ArSalesMove  WHERE TrnDate Between DATEADD(YEAR,-2,GetDate())   AND  GETDATE())
 GROUP BY Customer,StockCode,MONTH(TrnDate),Year(TrnDate)
 ORDER BY Customer,StockCode,TrnDate
;WITH enum AS 
(
Select Customer,StockCode, StartDate = CONVERT(DATETIME,    CONVERT(VARCHAR(50),MONTH(DATEADD(YEAR,-2,GetDate()) )) + '/01/' +   CONVERT(VARCHAR(50),Year(DATEADD(YEAR,-2,GetDate()) ))), --  MIN(TrnDate), 
 EndDate = GETDATE()-- MAX(TrnDate)
 FROM @temp

  Group BY Customer,StockCode 

  UNION ALL

SELECT Customer,StockCode, DATEADD(MONTH, 1, StartDate), EndDate
FROM enum 
WHERE StartDate < EndDate   
) 

INSERT INTO @tempSales (TrnDate, Customer,StockCode,InvoiceValue,GroupID)
SELECT  
e.StartDate,
e.Customer, 
e.StockCode,
InvoiceValue = ISNULL(t.InvoiceValue, 0), GroupID
FROM enum e
LEFT JOIN  @temp t ON  e.StartDate = t.TrnDate AND   e.StockCode =       t.StockCode AND e.Customer = t.Customer
ORDER BY e.Customer,e.StockCode,  e.StartDate

SET @counter = 0
UPDATE @tempSales 
SET @counter = tt.GroupID = @counter + 1
FROM @tempSales  tt
WHERE  CASE WHEN tt.InvoiceValue <> 0 THEN 1 ELSE 0 END = 1

SELECT (Select Name From ArCustomer Where RTRIM(Customer) = d.Customer) as    Name,
d.Customer,d.StockCode,
(Select [Description] From InvMaster Where RTRIM(StockCode) = d.StockCode)   as [Description],
d.LastSaleDate,d.MonthsSinceLastSale,d.ZeroAvg,d.Flag  FROM (
SELECT   c.Customer,c.StockCode,c.LastSaleDate,c.MonthsSinceLastSale,c.ZeroAvg,c.Flag 
FROM (
SELECT   b.Customer,b.StockCode,b.LastSaleDate,b.MonthsSinceLastSale,b.ZeroAvg,CASE WHEN    MonthsSinceLastSale > ZeroAvg + 1 THEN 1 ELSE 0 END as Flag --Add one month  cusion..
FROM (
SELECT a.Customer,a.StockCode,
 AVG(a.ZeroCount) as ZeroAvg,
(SELECT COUNT(TrnDate) as MonthsSinceLastSale FROM @tempSales
 WHERE Customer = a.Customer AND StockCode = a.StockCode AND  TrnDate   BETWEEN (SELECT MAX(TrnDate) FROM @tempSales tt WHERE Customer = a.Customer AND    StockCode = a.StockCode AND InvoiceValue <> 0)  AND GETDATE()) as   MonthsSinceLastSale,
 (SELECT MAX(TrnDate) FROM @tempSales tt WHERE Customer = a.Customer AND    StockCode = a.StockCode AND  InvoiceValue<> 0) as LastSaleDate
 FROM (
 Select COUNT(z.GroupID) as ZeroCount,z.Customer,z.StockCode,z.GroupID 
 FROM (

 SELECT  x.ID,x.TrnDate,    x.Customer,x.StockCode,x.InvoiceValue,ISNULL(x.GroupID,0) as GroupID
 FROM (
 SELECT t1.ID,t1.TrnDate, t1.Customer,t1.StockCode,t1.InvoiceValue,
 (--Fill Back null Values...
  SELECT t2.GroupID
  FROM @tempSales t2
  WHERE t2.ID = (
    SELECT MAX(t3.ID)
    FROM @tempSales t3
    WHERE t3.ID <= t1.ID
    AND GroupID IS NOT NULL
   )
  ) AS GroupID
 FROM @tempSales t1
 ) as x
 ) as z

 WHERE z.InvoiceValue = 0
 GROUP BY z.GroupID,z.Customer,z.StockCode
  ) as a
  GROUP BY  Customer,StockCode
  ) as b
  WHERE b.LastSaleDate IS NOT NULL
  ) as c
  Where c.Flag = 1
  ) as d 
 ORDER BY d.Customer,d.StockCode