如何将此迭代解决方案转换为基于集合的解决方案


/*
Stored Procedure
April 30, 2021
Mohamad Chaker
*/
USE CIS111_BookStoreMC
GO
--drop the procedure
IF OBJECT_ID('spAssetInfo') IS NOT NULL
DROP PROC spAssetInfo 
GO
--Create the stored procedure
CREATE PROC spAssetInfo
AS
--Create a temporary table to display the inventory
SELECT AssetID, Description, Cost, PurchaseDate 
INTO #temptable
FROM Assets
--Add a new column to the temporary table displaying the date an asset is completely depreciated
ALTER TABLE #temptable ADD CurrentValue MONEY
DECLARE @years INT;
DECLARE @currentYear INT;
SET @currentYear = YEAR(getdate());
DECLARE @cost MONEY;
--Add a new column to the temporary table to display the current value of the item in the current year
ALTER TABLE #temptable ADD CompleteDepreciationYear DATE
--@value holds the cost of an asset and is used to check when the value of an asset drops low
DECLARE @value MONEY;
SET @value = 0.00;
--@counter is an int that I used to iterate over the table rows
DECLARE @counter INT;
--@depreciationNum holds the amount of years until an item is completely depreciated to be later used in DATEADD() 
DECLARE @depreciationNum INT;
SET @counter = 1;
DECLARE @assetsTableSize INT;
SET @assetsTableSize = (SELECT COUNT(*) FROM Assets);
WHILE (@counter <= @assetsTableSize)
BEGIN
--Current Value
SET @years = @currentYear - (select YEAR(PurchaseDate) From Assets Where AssetID = @counter);
SET @cost = (select Cost From Assets Where AssetID = @counter);
--calculate current value of each asset
WHILE(@years>0)
BEGIN
SET @cost = @cost * 0.8;
SET @years = @years - 1;
END
--add the current value of each asset to the temporary table
UPDATE #temptable 
SET CurrentValue = @cost
WHERE AssetID = @counter;

--Deprection Year
SET @depreciationNum = 0;
SET @value = (select Cost From Assets Where AssetID = @counter);
WHILE(@value >0.1)
BEGIN  
SET @value = @value * 0.8;
SET @depreciationNum = @depreciationNum + 1;
END
--add the date each asset is completely depreciated to the temporary table
UPDATE #temptable 
SET CompleteDepreciationYear = CAST(DATEADD(year, @depreciationNum, (select PurchaseDate From Assets Where AssetID = @counter)) AS DATE)
WHERE AssetID = @counter;
--increment the counter
SET @counter = @counter + 1;
END
--display the assets inventory
SELECT * FROM #temptable

提示:显示资产库存和当前价值(每年减去20%的折旧(。还显示每个项目的年份完全贬值。

基本上,我试图显示一个带有PurchaseDate的资产库存,在项目完全折旧的日期,资产每年折旧20%。我尝试创建一个临时表,并将一些资产表列复制到其中,然后添加一列用于资产完全贬值的日期。

我使用迭代解决方案实现了这一点,但有人建议我在SO上发帖,尝试使用基于集合的实现来实现这一点。我是SQL的新手,刚刚了解到它是一种基于集合的语言,它不太适合迭代解决方案。

提前谢谢!

计算当前值的公式为:

CurrentValue = InitialValue * (1-0.2)^(Today - InitialDate)

要查找资产将达到0.1的年数:

CCD_ 2。从两边取日志:

Log(0.1) = Log(CurrentValue * Log(0.8^NumberOfYears)

Log(0.1) = Log(CurrentValue) + Log(0.8^NumberOfYears)

Log(0.1) = Log(CurrentValue) + NumberOfYears * Log(0.8)

[Log(0.1) - Log(CurrentValue)] / Log(0.8) = NumberOfYears

您可以创建一个使用此公式的函数,并返回NumberOfYear:

CREATE  FUNCTION GetNumberOfYears(
@InitialValue FLOAT
)
RETURNS FLOAT
AS
BEGIN
DECLARE @CurrentValue FLOAT,
@InitialValue FLOAT,
@YearsToZero FLOAT;
-- CurrentValue Formula
SET @CurrentValue = @InitialValue * POWER(CAST(0.8 AS FLOAT), YEAR(GETDATE() - YEAR(PurchaseDate));
-- NumberOfYears Formula
SELECT @YearsToZero = (LOG(0.1) - LOG(@CurrentValue)) / LOG(0.8);
RETURN @YearsToZero;
END

它会给你年数(例如54.6724159年(。

然后像SELECT GetNumberOfYears(Cost) FROM Assets一样使用

或者,您可以直接从SELECT使用:

SELECT
Cost * POWER(CAST(0.85 AS FLOAT), YEAR(GETDATE()) - YEAR(PurchaseDate)) AS CurrentValue,
(LOG(0.1) - LOG( [the above CurrentValue formula] )) / LOG(0.8) AS YearsToZero
FROM Assets

相关内容

最新更新