0

下面是函數:需要優化TSQL表值函數

CREATE FUNCTION dbo.agedItemResult(@ILC VARCHAR(30)) 
    RETURNS @AgedTable TABLE (
ItemID INT, 
ItemLookupCode VARCHAR(30), 
[Month] INT, 
[Year] INT, 
Aged INT, 
Debug01 VARCHAR(MAX), 
Debug02 VARCHAR(MAX), 
Debug03 VARCHAR(MAX), 
Debug04 VARCHAR(MAX), 
Debug05 VARCHAR(MAX) 
) 
AS 
BEGIN 

DECLARE @TotalSold INT 
DECLARE @AdjustmentQty INT 
DECLARE @FirstRcvdStart DATETIME 
DECLARE @FirstRcvdEnd DATETIME 
--DECLARE @ILC VARCHAR(MAX) 
--DECLARE @ItemID INT 
DECLARE @MovingQty INT 
DECLARE @MovingMonthStart DATETIME 
DECLARE @MovingMonthEnd DATETIME 
DECLARE @CurrentMonthStart DATETIME 
DECLARE @CurrentMonthEnd DATETIME 
DECLARE @CurrentRcvd INT 
DECLARE @NumMonths INT 
DECLARE @AgeReached INT 
/*DECLARE @AgedTable TABLE ( ItemID INT, 
          ItemLookupCode VARCHAR(MAX), 
          [Month] INT, 
          [Year] INT, 
          Aged INT, 
          Debug01 VARCHAR(MAX), 
          Debug02 VARCHAR(MAX), 
          Debug03 VARCHAR(MAX), 
          Debug04 VARCHAR(MAX), 
          Debug05 VARCHAR(MAX) 
          )*/ 

--SET @ILC = '21208641' 
SET @TotalSold   = (SELECT SUM(Sold) FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC) 
SET @AdjustmentQty  = (SELECT SUM(HQAdjustment) FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC) 
SET @FirstRcvdStart  = (SELECT TOP 1 FirstTransferred FROM JSInventorySnapShot ORDER BY FirstTransferred ASC) 
SET @FirstRcvdEnd  = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, @FirstRcvdStart)+1,0))) 
SET @CurrentMonthStart = (SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, GETDATE()),0))) 
SET @CurrentMonthEnd = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, GETDATE())+1,0))) 
SET @NumMonths   = (SELECT CASE 
          WHEN DATEPART(DAY, @FirstRcvdStart) > DATEPART(DAY, @CurrentMonthEnd) 
           THEN DATEDIFF(MONTH, @FirstRcvdStart, @CurrentMonthEnd) - 1 
           ELSE DATEDIFF(MONTH, @FirstRcvdStart, @CurrentMonthEnd) 
          END) + 1 
SET @MovingQty   = @TotalSold 
SET @CurrentRcvd  = ISNULL((SELECT SUM(Rcvd) FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC AND [Month] = Month(@FirstRcvdStart)), 0) + @AdjustmentQty 
SET @MovingMonthStart = @FirstRcvdStart 
SET @MovingMonthEnd  = @FirstRcvdEnd 
SET @MovingQty   = @MovingQty - @CurrentRcvd 
SET @AgeReached   = 0 

WHILE(@NumMonths > 0) 
BEGIN 
    IF (@CurrentRcvd = 0) 
    BEGIN 
     INSERT INTO @AgedTable (ItemID, ItemLookupCode, [Month], [Year], Aged, Debug01) 
      SELECT (SELECT TOP 1 ItemID FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC), 
         @ILC, 
         MONTH(@MovingMonthStart), 
         YEAR(@MovingMonthStart), 
         0, 
         @AdjustmentQty 
    END 
    ELSE 
    BEGIN 
     IF(@MovingQty > 0) 
     BEGIN 
      INSERT INTO @AgedTable (ItemID, ItemLookupCode, [Month], [Year], Aged, Debug01) 
       SELECT (SELECT TOP 1 ItemID FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC), 
          @ILC, 
          MONTH(@MovingMonthStart), 
          YEAR(@MovingMonthStart), 
          0, 
          @AdjustmentQty 
     END 
     ELSE 
     BEGIN 
      IF (@AgeReached = 1) 
      BEGIN 
       INSERT INTO @AgedTable (ItemID, ItemLookupCode, [Month], [Year], Aged) 
        SELECT (SELECT TOP 1 ItemID FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC), 
           @ILC, 
           MONTH(@MovingMonthStart), 
           YEAR(@MovingMonthStart), 
           @CurrentRcvd 
      END 
      ELSE 
      BEGIN 
       INSERT INTO @AgedTable (ItemID, ItemLookupCode, [Month], [Year], Aged) 
        SELECT (SELECT TOP 1 ItemID FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC), 
           @ILC, 
           MONTH(@MovingMonthStart), 
           YEAR(@MovingMonthStart), 
           (-1 * @MovingQty) 
        SET @AgeReached = 1 
      END 
     END 
    END 
    SET @NumMonths   = @NumMonths - 1 
    SET @MovingMonthStart = (SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, @MovingMonthStart)+1,0))) 
    SET @MovingMonthEnd  = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, @MovingMonthEnd)+2,0))) 
    SET @CurrentRcvd  = ISNULL((SELECT SUM(Rcvd) FROM JSInventorySnapShot WHERE ItemLookupCode = @ILC AND [Month] = Month(@MovingMonthStart)), 0) 
    SET @MovingQty   = @MovingQty - @CurrentRcvd 
    END 
    RETURN 
END 

下面是它概括地說:

首先,我們發現曾經收到或移動,並使用日期作爲第一項開始日期。然後我們找到該項目的總銷售額,並開始從銷售中扣除收款額。其餘部分被視爲已過期(未售出),並在下個月進行評估。然後我們移動到下個月並重復這個過程,直到我們遇到負數或0爲止。如果我們輸入負數,那麼這意味着我們已經達到了一個月以上的訂單,而且這個數量已經過期(不出售)。如果有更多的月份需要評估,那麼任何其他收到的數額在默認情況下都被視爲已過期,因爲它顯然未售出。

下面是用於評估表樣本數據:

ID  ItemID ItemLookupCode HQAdjustment FirstTransferred  Rcvd RcvdDateEarly   RcvdDateLate   Sold SoldDateEarly   SoldDateLate   Sales Month Year StartOfMonthQty EndOfMonthQty 
17350 188993 21208641  0    2012-04-05 13:29:14.000 48  2012-04-27 11:00:40.100 2012-04-27 11:00:40.100 40  2012-04-05 13:29:14.000 2012-04-30 12:50:13.000 75.20 4  2012 0    8 
34427 188993 21208641  0    2012-04-05 13:29:14.000 120  2012-05-22 10:14:40.213 2012-05-22 10:14:40.213 24  2012-05-04 17:42:12.000 2012-05-29 10:22:10.000 44.72 5  2012 8    104 
48437 188993 21208641  0    2012-04-05 13:29:14.000 0  NULL     NULL     12  2012-06-02 16:24:45.000 2012-06-21 11:15:05.000 22.36 6  2012 104    92 
62369 188993 21208641  0    2012-04-05 13:29:14.000 60  2012-07-16 12:57:33.330 2012-07-16 12:57:33.330 9  2012-07-11 14:42:01.000 2012-07-25 14:58:41.000 16.22 7  2012 92    143 
75781 188993 21208641  0    2012-04-05 13:29:14.000 0  NULL     NULL     2  2012-08-01 12:56:10.000 2012-08-14 19:01:00.000 4.01 8  2012 143    141 

這裏是我的上述數據函數的結果:

ItemLookupCode Month Rcvd Sold Aged 
21208641  4  48  40  0 
21208641  5  120  24  81 
21208641  6  0  12  0 
21208641  7  60  9  60 
21208641  8  0  2  0 

這告訴我,我們銷往接受一切四月。 5月再次訂購,賣出了一些,但仍留下庫存(年齡)。然後,在7月份沒有出售庫存的情況下,我們再次訂購了庫存,因此庫存自動被視爲已過期。

此功能的目的是停止上面發生的事情。這是訂購已經陳舊(未售出)庫存的物品。它也用於評估一個部門的年齡有多大,如果我們應該考慮開始銷售以擺脫陳舊的物品。

問題是我們有不少於40,000個項目要評估。此功能適用於單件物品,但100件物品需要30秒。我希望有人能來很長時間,看看我的功能,並意識到我正在完全錯誤的方式。如果我能夠完成內聯計算並將其餘部分進行優化。

基本上,我需要這個簡化的僞代碼:

Foreach (Month2Date) 
If AllInventoryAged = 1 Then //This says we've reached our sales:rcved thresh-hold and all received inventory is aged from here on out. 
    ThisMonthAged = RcvedForMonth 
Else 
    TotalSales - RcvedForMonth = Aged 
    If Aged < 0 Then 
     ThisMonthAged = Aged * -1 //We received more than sold so it's negative and we have hit our sales:rcved thresh-hold. 
     AllInventoryAged = 1 //Anything received from this point on is aged. 
    Else  
     ThisMonthAged = 0 //We received less this month then sold. A good thing. 
     TotalSales = Aged //We carry on the remainder for further evaluation 

我希望我一直在解釋自己這次徹底。對不起,這很久了。我只是想涵蓋我在上一篇文章中提到的所有問題。

+0

我沒有得到的數字是如何計算的。爲什麼在第5個月的年齡= 81,而不是96 = 120-24? –

+0

@GordonLinoff第5個月的年齡爲81歲,因爲您購買的是TOTAL銷售額 - 而不是該月的銷售額。這將是87,然後從第一個月減去48的接收。 39.它是積極的事實說,我們賣掉了第一個月的所有接收,而0年齡。攜帶39到下個月,並從中減去接收。給你-81。這意味着我們賣出了當月收到的所有81臺。它是負面的事實表明我們收到的不只是銷售。從那時起,任何進一步的庫存都會自動變老,因爲我們首先出售最早的庫存。 – jayEss

+0

你只是試圖獲得總銷售額和總收入的累積總額之間的差額?您可以在單個查詢中執行此操作。 –

回答