SQL Percent Error. Trouble with trying to use ABS() - sql

I am trying to find the Percent error of two columns for each row.
Currently I tried
UPDATE Weather
SET PercentError=ActualTemp - ForecastTemp / ActualTemp * 100
Which I know is in correct because when i do the calculations it doesn't match up with what the sql gives me. I then tried to use something along the lines of
UPDATE Weather
SET PercentError=ABS (ActualTemp - ForecastTemp) / ActualTemp * 100
But when i do this I just get 0 for my Percent error. I used ABS because I know it works with an INT but wanted to see if it would work when subtracting two columns.
I have been looking up how to subtract two columns using abs but they just use ABS to turn their number into positive and never use it in the equation itself. Is anyone able to point me in the right direction on how to get this to work correctly?
*Using Microsoft sql server

It's doing integer calculations. Try floating point math:
UPDATE Weather
SET PercentError=
(100.0 * ABS (ActualTemp - ForecastTemp)) / ActualTemp
Note that I placed the 100 in front of the equation, and forced the multiplication before the division.

How bout fixing the parentheses?
UPDATE Weather
SET PercentError = (ActualTemp - ForecastTemp) * 100.0 / ActualTemp ;
The 100.0 ensures that the division is not integer division.
Negative numbers seem reasonable, but you can include ABS():
UPDATE Weather
SET PercentError = ABS(ActualTemp - ForecastTemp) * 100.0 / ActualTemp ;

Related

Float precision in Bigquery [duplicate]

We don't have decimal data type in BigQuery now. So I have to use float
But
In Bigquery float division
0.029*50/100=0.014500000000000002
Although
0.021*50/100=0.0105
To round the value up
I have to use round(floatvalue*10000)/10000.
Is this the right way to deal with decimal data type now in BigQuery?
Depends on your coding preferences - for example you can just use simple ROUND(floatvalue, 4)
Depends on how exactly you need to round - up or down - you can respectively adjust expression
For example ROUND(floatvalue + 0.00005, 4)
See all rounding functions for BigQuery Standard SQL at below link
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#rounding-functions
Note that this question deserves a different answer now.
The premise of the question is "We don't have decimal data type in BigQuery now."
But now we do: You can use NUMERIC:
SELECT CAST('0.029' AS NUMERIC)*50/100
# 0.0145
Just make your column is NUMERIC instead of FLOAT64, and you'll get the desired results.
Rounding up in most SQL dialects is not a built-in function unless you're fortunate enough to be rounding up to an integer. In this case, CEIL is a quick and reliable solution.
In the case of rounding decimals up, we can also leverage CEIL, albeit with a couple of additional steps.
The procedure:
Multiply your value to move the last decimal to the tenths position. Ex. 18.234 becomes 1823.4 by multiplying by 100. (n * 100)
Use CEIL() to round up to the nearest integer. In our example, CEIL(n) = 1824.
Divide this result by the same figure used in step 1. In our example, n / 100 = 18.24.
Simplifying these steps leaves us with the below logic:
SELECT CEIL(value * 100) / 100 as rounded_up;
The same logic can be used to round down using the FLOOR function as such:
FLOOR(value * 100) / 100 AS rounded_down;
Thanks to #Mureinik for this answer.

How to use bigquery round up results to 4 digits after decimal point?

We don't have decimal data type in BigQuery now. So I have to use float
But
In Bigquery float division
0.029*50/100=0.014500000000000002
Although
0.021*50/100=0.0105
To round the value up
I have to use round(floatvalue*10000)/10000.
Is this the right way to deal with decimal data type now in BigQuery?
Depends on your coding preferences - for example you can just use simple ROUND(floatvalue, 4)
Depends on how exactly you need to round - up or down - you can respectively adjust expression
For example ROUND(floatvalue + 0.00005, 4)
See all rounding functions for BigQuery Standard SQL at below link
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#rounding-functions
Note that this question deserves a different answer now.
The premise of the question is "We don't have decimal data type in BigQuery now."
But now we do: You can use NUMERIC:
SELECT CAST('0.029' AS NUMERIC)*50/100
# 0.0145
Just make your column is NUMERIC instead of FLOAT64, and you'll get the desired results.
Rounding up in most SQL dialects is not a built-in function unless you're fortunate enough to be rounding up to an integer. In this case, CEIL is a quick and reliable solution.
In the case of rounding decimals up, we can also leverage CEIL, albeit with a couple of additional steps.
The procedure:
Multiply your value to move the last decimal to the tenths position. Ex. 18.234 becomes 1823.4 by multiplying by 100. (n * 100)
Use CEIL() to round up to the nearest integer. In our example, CEIL(n) = 1824.
Divide this result by the same figure used in step 1. In our example, n / 100 = 18.24.
Simplifying these steps leaves us with the below logic:
SELECT CEIL(value * 100) / 100 as rounded_up;
The same logic can be used to round down using the FLOOR function as such:
FLOOR(value * 100) / 100 AS rounded_down;
Thanks to #Mureinik for this answer.

Different calculation in SQL Server and Excel

This is my formula. I put it in a SQL Server stored procedure:
DECLARE #Var01 float
SET #Var01 = 1164.83 * (1 - 3.3387306 * LOG(0.00459418151829729) + 1.426559 * POWER(LOG(0.00459418151829729),2)) / (1 - 3.4680733 * LOG(0.00459418151829729) + 1.8779192 * POWER(LOG(0.00459418151829729), 2) - 0.21223784 * POWER(LOG(0.00459418151829729), 3) - 0.0035814371 * POWER(LOG(0.00459418151829729), 4) - 0.90903163 * POWER(10, -4) * POWER(LOG(0.00459418151829729), 5)) - 459.67
The result is: 214.630185149416
Then I'm trying to compare to excel, the formula as below:
=1164.83 * (1 - 3.3387306 * LN(0.00459418151829729) + 1.426559 * (LN(0.00459418151829729)) ^ 2) / (1 - 3.4680733 * LN(0.00459418151829729) + 1.8779192 * (LN(0.00459418151829729)) ^ 2 - 0.21223784 * (LN(0.00459418151829729)) ^ 3 - 0.0035814371 * (LN(0.00459418151829729)) ^ 4 - 0.90903163 * 10 ^ -4 * (LN(0.00459418151829729)) ^ 5) - 459.67
The result is: 211.981432072480
The question is, which one is correct? Any Idea? What the calculation is different?
The comments have speculated that this is roundoff error, and that SQL Server is more reliable because it uses more precise floats than Excel. This is wrong. The relative error is about 1%. You do not get relative errors of 1% when you perform a short computation while making roundoff errors of 10-13% unless you are subtracting nearly equal large numbers.
I suggested breaking down the computation to see if SQL Server and Excel agree on the pieces, to see where they diverged. This would have worked. It's like stepping through a program instead of just saying that the end result is not what was desired. You can do a binary search to find the problem rapidly, but the OP didn't provide any additional information.
The computation being performed is
There isn't any cancelation of huge numbers that might cause a large relative error. So, I tried to solve
to see what error in the denominator would result in this miscalculation. With a little calculus, I could check for typos in the constants. The solution is x=-0.410829. That's almost exactly the last term in the denominator. So, the answer isn't that one of these environments produces 1% relative errors in simple floating point calculations, it's that a term was dropped in the denominator. This would have been obvious from breaking the calculation into pieces.
The last term is the only one with something like POWER(10,-4). Could it be that this is carried out using integer arithmetic instead of floating point, so that it evaluates to 0 instead of 0.0001? Yes, apparently that's what SQL Server does. It's like 1/2=0 in integer arithmetic. If you want a decimal output you have to give it a decimal input. Cast the 10 to decimal, change it to POWER(10.0,-4), use 0.0001, or use proper scientific notation for the whole coefficient.

Math in SQL query not working

I have a sql query (SQL server 2005) that's creating a var and doing some math. The math works when the ticket count is 0 or 250000, but it's not creating a decimal point when the ticket count is any other value. (It reads 0.) Here is the query -
SELECT ticketCount, ((250000 - ticketCount) / 250000) * 100 AS percentSold
FROM raffleTickets
Where ticketCount in the DB is how many tickets of 250000 remain to be sold. If ticketCount is 250000, percentsold is 0, which is correct. If ticketCount is 0, percentSold is 100, which is correct. For all other values, percentSold is returning 0.
Please help! Thanks.
SQL Server does integer division (this varies among databases).
You can easily fix this by putting a decimal point after the constants:
SELECT ticketCount, ((250000.0 - ticketCount) / 250000.0) * 100.0 AS percentSold
FROM raffleTickets;
If you want the integer portion, then you can cast() the result back to an integer. Alternatively, you can use the str() function to convert the value of percentSold to a string with the appropriate number of decimal points.
Your formula is correct,
PercentSold = (TotalTickets - TicketsRemaining) / TotalTickets
But what is the Domain and Range of the above function? Your numbers are all expressed as integer, but you probably want to calculate using Real.
PercentSold = ( ( TotalTickets - TicketsRemaining )*100.0) / (TotalTickets)
This forces the calculation to be done in Real. Languages that know how to declare variables and calculations in specific types (i.e. Domains) can make this clearer, more apparent.
Wanting to represent a real number with a certain precision means you want to perform output formatting. SqlServer must have a way to specify output format for numbers in the Real Domain. I defer to SqlZoo.net for their answer to formatting.
The only thing you need to do is putting plus or minus 0.0 in your formula.
SELECT ticketCount, ((250000 - ticketCount - 0.0) / 250000) * 100 AS percentSold
FROM raffleTickets

Get an accurate percentage calculation

I am trying to divide one number by another in a SQL view. I'm dividing two columns that are each of type int, and the problem is that its giving me a rounded output, rather than an accurate one.
Here is my select:
SELECT numberOne, numberTwo, (numberOne*100/NULLIF(numberTwo, 0)) as PctOutput
This is working, but when it dives 3 by 37 its giving me 8 instead of 8.108.
How would I modify this to give me an accurate answer? Do I need to cast the numbers out of ints? if so - into what?
Try an implicit cast:
SELECT
numberOne,
numberTwo,
((1.0*numberOne)*100/NULLIF(1.0*numberTwo, 0)) as PctOutput
**--Cast the denominator as Float**
SELECT 3 * 100 / NULLIF(CAST(37 AS FLOAT),0) -- 8.10810810810811
**--Multiply by 1.0 in either numerator OR denominator**
SELECT 3 * 100 / NULLIF(37 * 1.0,0) -- 8.108108
SELECT 3.0 * 100 / NULLIF(37,0) -- 8.108108
**--Convert it to decimal**
SELECT CONVERT(DECIMAL(25,13), 3) * 100 /
NULLIF(CONVERT(DECIMAL(25,13), 37),0) -- 8.108108108
You need to cast the numbers from INT into either float or decimal.
If you use literals, they will likely be decimal (NUMERIC), not float (http://stackoverflow.com/questions/1072806/sql-server-calculation-with-numeric-literals)
Note that if you use decimal, you should be aware of the rules of scale and precision in division if you have numbers near the boundaries where you might lose precision:
http://msdn.microsoft.com/en-us/library/ms190476.aspx
In SQL Server the result is always of the same type as the inputs. So yes you do need to convert the inputs.
I generally convert using convert(decimal(9,2),numberOne) but depending you may want to convert(real,numberOne) or use a different level of precision.