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

Sql 如何将此迭代解决方案转换为基于集合的解决方案,sql,sql-server,stored-procedures,set-based,Sql,Sql Server,Stored Procedures,Set Based,提示:显示资产库存以及当前值减去每年20%的折旧。同时显示每个项目将在哪一年完成 完全贬值了 基本上,我试图显示一个带有PurchaseDate和项目完全折旧日期的资产库存,资产每年折旧20%。我尝试创建一个临时表,并将一些资产表列复制到该表中,然后添加一个列作为资产完全折旧的日期 我使用迭代解决方案实现了这一点,但有人建议我继续发布,以便尝试使用基于集合的实现来实现这一点。我对SQL是新手,并且刚刚了解到它是一种基于集合的语言,对于迭代解决方案来说不是很好 提前谢谢你 计算当前值的公式为: C

提示:显示资产库存以及当前值减去每年20%的折旧。同时显示每个项目将在哪一年完成 完全贬值了

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

我使用迭代解决方案实现了这一点,但有人建议我继续发布,以便尝试使用基于集合的实现来实现这一点。我对SQL是新手,并且刚刚了解到它是一种基于集合的语言,对于迭代解决方案来说不是很好


提前谢谢你

计算当前值的公式为:

CurrentValue=初始值*1-0.2^今天-初始日期

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

0.1=当前值*1-0.2^年数。从两边取原木:

Log0.1=LogCurrentValue*Log0.8^数年

Log0.1=LogCurrentValue+Log0.8^数年

Log0.1=LogCurrentValue+NumberOfYears*Log0.8

[Log0.1-LogCurrentValue]/Log0.8=年份数

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

/*
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

它将为您提供年数,例如54.6724159年

然后像从资产中选择GetNumberOfYearsCost一样使用它

或者,您可以直接从您的选择中使用:

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

您是否将折旧定义为将前一年的价值减少20%,而不是原值的20%,并将全部折旧定义为价值低于0.1?样本数据和预期结果将大有帮助。
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