我正在使用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 LOSSyear
这种情况有什么解决办法吗?请帮我调查一下。谢谢!

最佳答案

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年开始,然后考虑到这个数量在2012200%年增长了两倍,在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

对于1netincome_first,它给出…
ABS( ( -1400 - 200 ) / 200 ) + 1      = ABS( -1600 / 200 ) + 1 = ABS( -8 ) + 1 = 8 + 1 = 9

对于netincome_first = 200netincome_last = 1800,它给出…
ABS( ( 1400 - ( -200 ) / -200 ) + 1  = ABS( 1600 / -200 ) + 1  = ABS( -8 ) + 1 = 8 + 1 = 9

对于netincome_first = 200netincome_last = -1400,它给出…
ABS( ( -1800 - ( -200 ) / -200 ) + 1 = ABS( -1600 / -200 ) + 1 = ABS( 8 ) + 1  = 8 + 1 = 9

netincome_first = -200的第二个参数是覆盖的周期数的倒数。例如,如果上面的例子是从netincome_last = 1400netincome_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/

10-16 13:17