使用SQL Server POWER函数将负基数提高到十进制功率

时间:2017-04-16 05:46:12

标签: sql sql-server database sql-server-2014

我正在使用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

这种情况有没有解决方法?请帮我调查一下。谢谢!

1 个答案:

答案 0 :(得分: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,
       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.002012开始,然后在200% 2013 $600.00 $1800.00内考虑此数量增加三倍/增长,此金额再次在2014中增加到200%三倍。我们知道这两年的增长率都是( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear + 1 ) ) ) - 1

如果我们使用给定的公式......

( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 + 1 ) ) ) - 1 = ( 9 ^ ( 1 / 3 ) ) - 1 = 1.080...

......我们得到......

2

...而不是我们期望的+ 1。如果从公式中删除( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 ) ) ) - 1 = ( 9 ^ ( 1 / 2 ) ) - 1 = 2 ,我们就会得到......

( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear ) ) ) - 1

因此我们可以将公式更正为......

$-200.00

如果两个数字都是正数且最近的数字大于前者,则此公式将给出正确的答案。

如果值均为负值且较近的值较小(例如$-1,800.00后紧跟$200.00,即如果已经丢失,则会收到相同的结果,就像数字一样两者都是积极的,而后者则更大,例如$1,800.00后跟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 )

如果您希望在一行中使用它,那就是......

netincome_first

要注意的第一点是基于netincome_lastnetincome_last的一对减法。这是为了衡量您迟早要衡量两个值之间的差异的增长。

其次,我们公式的第一部分用于指示netincome_lastSIGN()的变化方向。如果数字为负数,则-1会返回1,如果数字为正,则返回POWER()。当我们将此数字乘以变化的幅度时,我们将能够指出是否已经出现增长或损失以及变化的大小。

第三,ABS( ( netincome_last - netincome_first ) / netincome_first ) + 1 的第一个论点是......

netincome_last

此公式衡量netincome_first相对于所涵盖期间数netincome_first的大小的倍数,无论是否出现增长或损失,以及netincome_last+ 1是。{/ p>

我们将1添加到除法结果中,以补偿因计算差异而导致的netincome_first netincome_first = 200值的丢失

为了说明,对于netincome_last = 1800ABS( ( 1800 - 200 ) / 200 ) + 1 = ABS( 1600 / 200 ) + 1 = ABS( 8 ) + 1 = 8 + 1 = 9 ,它给出了......

netincome_first = 200

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

netincome_first = -200

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

netincome_first = -200

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

POWER()

2012的第二个参数是所涵盖时期的倒数。例如,如果上述示例的时间段为20143,那么我们将考虑2个时段(2年)。在每个期间,净收入将增加两倍,即每个先前水平增加到9倍。我们可以通过查找9 ^ ( 1 1=/ 2 )的平方根来计算此值,即找到3

据说一个值的增长率等于减去一个值的任何时间。例如,如果它增加到先前水平的2倍,则称其增长率为200%(即它已增长- 1)。因此,在POWER()计算之后docker run -t -i --device=/dev/ttyUSB0 ubuntu bash

如果您有任何问题或意见,请随时发表评论。