Reputation: 427
I'm using SQL Server 2014 and I ran through an error using the POWER
function.
Below is the arithmetic formula that I am trying to do in my query.
growth rate = ((presentnetincome/pastnetincome) ^ (1/(presentyear-pastyear+ 1))) - 1
Below is the query that I have
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
However, I get an error
An invalid floating point operation occurred
when the row's netincome_first
is a negative number since they recorded a NET LOSS
that year
.
Are there any workarounds to this situation? Kindly help me investigate. Thanks!
Upvotes: 1
Views: 568
Reputation: 2236
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
Firstly, the given formula has an error in it, namely that presentyear - pastyear + 1
should read presentyear - pastyear
. To illustrate, please consider starting with $200.00
in the year 2012
, then consider this amount tripling / growing by 200%
in 2013
to $600.00
, and this amount again tripling to $1800.00
in 2014
. We know that the growth rate is 200%
for both years.
If we use the given formula of...
( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear + 1 ) ) ) - 1
... we get...
( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 + 1 ) ) ) - 1 = ( 9 ^ ( 1 / 3 ) ) - 1 = 1.080...
... instead of the 2
that we expect. If you drop the + 1
from the formula, we instead get...
( ( 1800 / 200 ) ^ ( 1 / ( 2014 - 2012 ) ) ) - 1 = ( 9 ^ ( 1 / 2 ) ) - 1 = 2
Thus we can correct the formula to...
( ( presentnetincome / pastnetincome ) ^ ( 1 / ( presentyear - pastyear ) ) ) - 1
This formula will give the correct answer if both numbers are positive and the more recent is larger than the former.
If the values are both negative and the more recent is smaller (such as with $-200.00
followed immediately by $-1,800.00
, i.e. if a loss has been taken, the same result is received as if the numbers had both been positive and the latter larger, such as with $200.00
followed by $1,800.00
. Both cases yield the same number, but the former reflects a rate of loss, i.e. negative growth.
If one of the values is negative then the formula will try to calculate the root of a negative number, which in half of all cases won't work with real numbers (the sort that we are using here) and in the other half would give a real, but wrong, number.
Thus a modified statement will need to be developed that will be able to handle all combinations of negative and positive amounts.
The single adapted formula I developed is...
SIGN( netincome_last -
netincome_first ) *
( POWER( ABS( ( netincome_last -
netincome_first ) /
netincome_first
) + 1,
1 / ( year_last -
year_first )
) - 1 )
If you would prefer it in a single line, it is...
SIGN( netincome_last - netincome_first ) * ( POWER( ABS( ( netincome_last - netincome_first ) / netincome_first ) + 1, 1 / ( year_last - year_first ) ) - 1 )
The first point to note is that there is a pair of subtractions based on netincome_first
and netincome_last
. This is to be expected as to measure growth you will sooner or later have to measure the difference between two values.
Secondly, the first part of our formula is used to indicate the direction of the change in netincome_last
from netincome_last
. Here SIGN()
will return -1
if the number is negative and 1
if it positive. When we multiply this number by the magnitude of the change we will be able to indicate if growth or loss has occurred and the size of that change.
Thirdly, the first argument of POWER()
is...
ABS( ( netincome_last -
netincome_first ) / netincome_first ) + 1
This formula measures the how many times larger netincome_last
is in relation to the size of netincome_first
for the number of periods covered, irrespective of whether or not growth or loss has occurred and what the signs of netincome_first
and netincome_last
are.
We add + 1
to the result of the division to compensate for the loss of 1
value of netincome_first
caused by calculating the difference
To illustrate, for netincome_first = 200
and netincome_last = 1800
it gives...
ABS( ( 1800 - 200 ) / 200 ) + 1 = ABS( 1600 / 200 ) + 1 = ABS( 8 ) + 1 = 8 + 1 = 9
For netincome_first = 200
and netincome_last = -1400
it gives...
ABS( ( -1400 - 200 ) / 200 ) + 1 = ABS( -1600 / 200 ) + 1 = ABS( -8 ) + 1 = 8 + 1 = 9
For netincome_first = -200
and netincome_last = 1400
it gives...
ABS( ( 1400 - ( -200 ) / -200 ) + 1 = ABS( 1600 / -200 ) + 1 = ABS( -8 ) + 1 = 8 + 1 = 9
For netincome_first = -200
and netincome_last = -1800
it gives...
ABS( ( -1800 - ( -200 ) / -200 ) + 1 = ABS( -1600 / -200 ) + 1 = ABS( 8 ) + 1 = 8 + 1 = 9
The second argument of POWER()
is the inverse of the number of periods covered. For instance, if the above examples were for the period of 2012
through to 2014
then we would be considering 2 periods (2 years). In each of these periods the nett income would have tripled, i.e. increased to 3
times each previous level. We can calculate this value by finding the square root of 9
, i.e. by finding 9 ^ ( 1 1=/ 2 )
.
A value is said to have grown by a rate equal to how any times larger it is subtract one. For example, where it increases to 3
times its previous level it is said to have a growth rate of 2
(i.e. it has grown 200%
). Hence the - 1
just after the POWER()
calculation.
If you have any questions or comments, then please feel free to post a Comment accordingly.
Upvotes: 1