我正在使用SQL Server 2014,使用POWER
函数时遇到错误。
下面是我在查询中尝试使用的算术公式。
growth rate = ((presentnetincome/pastnetincome) ^ (1/(presentyear-pastyear+ 1))) - 1
下面是我的问题
WITH i AS
(
SELECT DISTINCT
stockid,
first_value([year]) over (partition by stockid order by [year]) AS year_first,
first_value([year]) over (partition by stockid order by [year] desc) AS year_last,
first_value(netincomeaftertax) over (partition by stockid order by [year]) AS netincome_first,
first_value(netincomeaftertax) over (partition by stockid order by [year] desc) AS netincome_last
FROM
incomestatements i
)
SELECT
stockid,
POWER(netincome_first / CAST(netincome_last AS FLOAT), 0.2) - 1 AS growthRate
FROM i
但是,我得到一个错误
发生无效的浮点运算
当行的
netincome_first
是负数时,因为它们记录了NET LOSS
的year
。这种情况有什么解决办法吗?请帮我调查一下。谢谢!
最佳答案
WITH i AS ( SELECT DISTINCT stockid,
FIRST_VALUE( [year] ) OVER ( PARTITION BY stockid ORDER BY [year] ) AS year_first,
FIRST_VALUE( [year] ) OVER ( PARTITION BY stockid ORDER BY [year] DESC ) AS year_last,
FIRST_VALUE( netincomeaftertax ) OVER ( PARTITION BY stockid ORDER BY [year] ) AS netincome_first,
FIRST_VALUE( netincomeaftertax ) OVER ( PARTITION BY stockid ORDER BY [year] DESC ) AS netincome_last
FROM incomestatements i )
SELECT stockid,
SIGN( netincome_last -
netincome_first ) *
( POWER( ABS( ( netincome_last -
netincome_first ) /
netincome_first
) + 1,
1 / ( year_last -
year_first )
) - 1 ) AS growthShrinkageRate
首先,给定的公式有一个错误,即
presentyear - pastyear + 1
应该读取presentyear - pastyear
。为了说明这一点,请考虑从$200.00
年开始,然后考虑到这个数量在2012
到200%
年增长了两倍,在2013
年增长了两倍。我们知道这两年的增长率都$600.00
。如果我们使用给定的公式…
( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear + 1 ) ) ) - 1
…我们得到……
( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 + 1 ) ) ) - 1 = ( 9 ^ ( 1 / 3 ) ) - 1 = 1.080...
…而不是我们所期望的。如果你从公式中删除
$1800.00
,我们会得到……( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 ) ) ) - 1 = ( 9 ^ ( 1 / 2 ) ) - 1 = 2
因此我们可以修正公式…
( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear ) ) ) - 1
如果两个数字都是正数,且最近的数字大于前者,则此公式将给出正确答案。
如果两个值都为负,且最近的值较小(例如,用
2014
紧跟200%
,即,如果进行了损失,则接收相同的结果,就好像两个数字都是正的,而后者更大,例如用2
紧跟+ 1
。两种情况产生的数量相同,但前者反映的是损失率,即负增长。如果其中一个值是负数,那么公式将尝试计算负数的根,在所有情况下,一半的根对实数不起作用(我们在这里使用的那种类型),另一半则会给出一个实数,但错了。
因此,需要编制一份修改后的报表,该报表将能够处理正负金额的所有组合。
我开发的唯一一个适应公式是…
SIGN( netincome_last -
netincome_first ) *
( POWER( ABS( ( netincome_last -
netincome_first ) /
netincome_first
) + 1,
1 / ( year_last -
year_first )
) - 1 )
如果你喜欢一行的话,它是…
SIGN( netincome_last - netincome_first ) * ( POWER( ABS( ( netincome_last - netincome_first ) / netincome_first ) + 1, 1 / ( year_last - year_first ) ) - 1 )
要注意的第一点是有一对基于
$-200.00
和$-1,800.00
的减法。这是预期的,因为要衡量增长,你迟早要衡量两个值之间的差异。其次,我们的公式的第一部分用来指示从
$200.00
到$1,800.00
的变化方向。如果数字为负,netincome_first
将返回netincome_last
,如果数字为正,netincome_last
将返回netincome_last
。当我们将这个数字乘以变化的幅度时,我们就能够指出是否发生了增长或损失,以及变化的大小。第三,
SIGN()
的第一个论点是……ABS( ( netincome_last -
netincome_first ) / netincome_first ) + 1
这个公式测量了在所覆盖的周期数中,与
-1
的大小相关的1
大多少倍,而不管是否发生了生长或丢失,以及POWER()
和netincome_last
的迹象是什么。我们将
netincome_first
添加到除法结果中,以补偿由于计算差异而导致的netincome_first
值的损失。举例来说,对于
netincome_last
和+ 1
,它给出了…ABS( ( 1800 - 200 ) / 200 ) + 1 = ABS( 1600 / 200 ) + 1 = ABS( 8 ) + 1 = 8 + 1 = 9
对于
1
和netincome_first
,它给出…ABS( ( -1400 - 200 ) / 200 ) + 1 = ABS( -1600 / 200 ) + 1 = ABS( -8 ) + 1 = 8 + 1 = 9
对于
netincome_first = 200
和netincome_last = 1800
,它给出…ABS( ( 1400 - ( -200 ) / -200 ) + 1 = ABS( 1600 / -200 ) + 1 = ABS( -8 ) + 1 = 8 + 1 = 9
对于
netincome_first = 200
和netincome_last = -1400
,它给出…ABS( ( -1800 - ( -200 ) / -200 ) + 1 = ABS( -1600 / -200 ) + 1 = ABS( 8 ) + 1 = 8 + 1 = 9
netincome_first = -200
的第二个参数是覆盖的周期数的倒数。例如,如果上面的例子是从netincome_last = 1400
到netincome_first = -200
的时间段,那么我们将考虑2个时间段(2年)。在每一个时期,净收入都会增加三倍,即增加到以前每一水平的netincome_last = -1800
倍。我们可以通过求POWER()
的平方根,即通过求2012
来计算这个值。一个值的增长率等于它减去一的倍数。例如,当它增加到前一个水平的
2014
倍时,它的增长率称为3
(即它已经增长了9
)。因此,9 ^ ( 1 1=/ 2 )
计算之后。如果您有任何问题或意见,请随时发表相应的评论。
关于sql - 使用SQL Server POWER函数将负基数提高到十进制幂,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43434138/