这是功能:
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
这告诉我,我们卖掉了四月收到的所有东西。 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 :(得分:0)
我最终通过重新评估我想要做的事来解决这个问题。我能够使用递归CTE。您可以在此处查看我的相关“测试”代码: