0

関数は次のとおりです。

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 になるまでプロセスを繰り返します。負の数に達すると、これまでに販売された数より多くの注文をした月に達したことを意味し、その金額は期限切れと見なされます (販売していません)。評価する月がさらにある場合、FURTHER の受領金額は、明らかに販売されていないため、デフォルトで期限切れと見なされます。

評価に使用したテーブルのサンプル データを次に示します。

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

これは、4 月に受け取ったものをすべて販売したことを示しています。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

今回は自分自身を徹底的に説明したことを願っています。長くなってすみません。前回の投稿で私が持っていたすべての質問をカバーしたかっただけです。

4

1 に答える 1

0

私は最終的に、自分がやろうとしていたことを再評価することでこれを解決しました. Recursive CTE を使用できました。関連する「テスト」コードは次の場所にあります。

TSQL - 再帰 CTE が非効率的 - 代替手段が必要

于 2012-10-11T13:56:07.913 に答える