SQL Server:在另一个计算列中使用的计算列结果

时间:2017-02-17 15:15:43

标签: sql-server

我知道不可能有一个计算列考虑其计算另一个计算列。我发现硬件有以下错误:

"is not allowed to be used in another computed-column definition."

所以我有以下数据列,这些列并不重要,但只是让你理解我在做什么(引用的任何其他列都是标准的非计算列):

HardwareAssetDepreciableValue AS CONVERT(DECIMAL(7,2),HardwareAssetPurchaseValue - 
HardwareAssetSalvageValue)

HardwareAssetLifeSpan AS CONVERT(DECIMAL(6,2),DATEDIFF(day,HardwareAssetDateInstalled,
HardwareAssetEndOfLifeDate)) / 365

它们都是按预期计算和工作的,但是我遇到的问题是一组相当复杂的计算,但是想知道是否有人可以建议或帮助解决多个计算列问题的替代方案。

我的查询是:

HardwareAssetAccumulatedDepreciationValue AS CASE WHEN HardwareAssetDepreciationMethodID
 = '1' THEN CONVERT(DECIMAL(7,2),((HardwareAssetDepreciableValue / HardwareAssetLifeSpan)
/ 365)) WHEN HardwareAssetDepreciationMethodID = '2' THEN CONVERT(DECIMAL(7,2),
HardwareAssetAccumulatedDepreciationValue + ((1.5 *(1/HardwareAssetLifeSpan))*
HardwareAssetBookValue)/365) ELSE CONVERT(DECIMAL(7,2),
HardwareAssetAccumulatedDepreciationValue + ((2 *(1/HardwareAssetLifeSpan))
*HardwareAssetBookValue)/365) END

感谢任何帮助或建议!

3 个答案:

答案 0 :(得分:2)

当您使用计算列计算另一个列值时发生此错误 var filteredArray = self.manufacturerArray.filter { $0.manufacturer.range(of: srchVal, options: .caseInsensitive) != nil } ...

似乎你有低于计算列

is not allowed to be used in another computed-column definition.

然后你,用同样的方法计算下面的计算列

HardwareAssetDepreciableValue

你不应该这样做..相反,你应该使用基础计算

  

但是想知道是否有人可以建议或帮助解决多个计算列问题的替代方案。

目前,没有更好的选择,我能想到的一个解决方案是查询基表并使用已有的计算值

答案 1 :(得分:1)

计算列适用于"一个关闭" IMHO。

对于有点复杂的东西,我喜欢创建一个标量用户定义函数,并包装"迷你逻辑"在它。

这是一个简单的Northwind示例。它没有很多实际意义,但证明了这一点。

现在,我不喜欢以下的udfExampleUdfTwoDoubleUdfOne想法。但它可能对你有用。

它是一个工具库的想法。这是因为你要求其他想法。

Use Northwind
GO

create function dbo.udfExampleUdfOne(@OrderID as int, @ProductID int, @UnitPrice money )
        returns int
as
begin

declare @returnValue int = 0

select @returnValue = ISNULL(@OrderID,0) + ISNULL(@ProductID,0) + ISNULL(@UnitPrice,0)


return @returnValue;

end;

GO

create function dbo.udfExampleUdfTwoDoubleUdfOne(@udfOneResult int)
        returns int
as
begin

declare @returnValue int = 0

select @returnValue = ISNULL(@udfOneResult,0) * 2


return @returnValue;

end;


GO

SELECT TOP 1000 [OrderID]
      ,[ProductID]
      ,[UnitPrice]
      ,[Quantity]
      ,[Discount]
      , MyValueOne = dbo.udfExampleUdfOne(OrderID , ProductID , UnitPrice)
      , MyValueTwoWhichIsActuallyDoubleValueOne = dbo.udfExampleUdfTwoDoubleUdfOne(dbo.udfExampleUdfOne(OrderID , ProductID , UnitPrice))
  FROM [Northwind].[dbo].[Order Details]

APPEND

所以试图模仿你的例子

create function dbo.udfComputeHardwareAssetDepreciableValue(@HardwareAssetPurchaseValue int, @HardwareAssetSalvageValue int )
        returns int
as
begin

declare @returnValue int = 0

select @returnValue = ISNULL(@HardwareAssetPurchaseValue,0) - ISNULL(@HardwareAssetSalvageValue,0)


return @returnValue;

end;



create function dbo.udfComputeHardwareAssetLifeSpan(@HardwareAssetDateInstalled int, @HardwareAssetEndOfLifeDate int )
        returns int
as
begin

declare @returnValue int = 0

select @returnValue = CONVERT(DECIMAL(6,2),DATEDIFF(day,@HardwareAssetDateInstalled,
@HardwareAssetEndOfLifeDate)) / 365


return @returnValue;

end;

然后编写第三个封装了HardwareAssetAccumulatedDepreciationValue IF / THEN / CASE逻辑的UDF。

你〜可以将计算列传递给新的udfComputeHardwareAssetAccumulatedDepreciationValue函数。

即使你是新手,也应该花一点时间来挣扎这个概念作为最好的工具,以避免RBAR / CURSORS。

您可以从此处获取Northwind数据库:

https://technet.microsoft.com/en-us/library/ms143221(v=sql.105).aspx

是的,它可以从中创建非常古老但简单的演示。

答案 2 :(得分:0)

你可以让两个用户定义的列功能,我一直在寻找它但最后得到了,该功能可以访问计算出的所有列ND NON Computed ...

谢谢