Divide by zero error in SQL even though I excluded the zero cases? - sql

Here is the code that I've been trying to run:
SELECT C.* FROM
(SELECT
B.[OUTSIDE_ROW],
B.[INSIDE_ROW],
B.[r_HU_vac_ns],
B.[r_HU_vac_ns_MOE],
CASE WHEN B.[r_HU_vac_ns] = 0 THEN 999 ELSE B.[r_HU_vac_ns_MOE]/B.[r_HU_vac_ns] END AS [PCT]
FROM
(SELECT
A.[OUTSIDE_ROW],
A.[INSIDE_ROW],
(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT] AS [r_HU_vac_ns],
(1/A.[HU_VACANT]) * POWER(
CASE WHEN ((A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2) < POWER(A.[HU_VACANT_MOE], 2) + POWER(A.[HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) THEN POWER(A.[HU_VACANT_MOE], 2) + POWER(A.[HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) - (((A.[HU_VACANT] - A. [HU_vACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2))
ELSE POWER(A.[HU_VACANT_MOE], 2) + POWER(A. [HU_VACANT_SEASONAL_RECREATIONAL_MOE], 2) + (((A.[HU_VACANT] - A. [HU_vACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT]) * POWER(A.[HU_VACANT_MOE], 2)) END, 0.5) AS [r_HU_vac_ns_MOE]
FROM
(SELECT
[OUTSIDE_ROW],
[INSIDE_ROW],
SUM([ESTIMATE_1]) AS [HU_VACANT],
POWER(SUM(POWER([MOE_1], 2)), 0.5) AS [HU_VACANT_MOE],
SUM([ESTIMATE_2]) AS [HU_VACANT_SEASONAL_RECREATIONAL],
POWER(SUM(POWER([MOE_2], 2)), 0.5) AS [HU_VACANT_SEASONAL_RECREATIONAL_MOE]
FROM #TEST_TABLE
GROUP BY [OUTSIDE_ROW], [INSIDE_ROW]) A
WHERE A.[HU_VACANT] > 0) B ) C
WHERE C.[PCT] < 0.2
Every time I run it, I get the following error:
Msg 8134, Level 16, State 1, Line 533
Divide by zero error encountered.
However, if I take off the last line of code (the following WHERE clause) the code runs fine:
WHERE C.[PCT] < 0.2
Just from looking at my query, can anyone tell me what I'm doing wrong? I thought I eliminated all PCT values that were zero with the CASE WHEN statement below so this error is baffling me:
CASE WHEN B.[r_HU_vac_ns] = 0 THEN 999 ELSE B.[r_HU_vac_ns_MOE]/B.[r_HU_vac_ns] END AS [PCT]
If it helps, PCT is cast as floating point.
Thanks.

SQL Server reserves the right to rearrange calculations. That means that the calculation in a SELECT can happen before filtering occurs. This is true even when the filters are in subqueries and CTEs.
The only way to guarantee order of calculation is CASE. However, I think it is easier to just use NULLIF(), an ANSI standard function. Instead of logic like this:
(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/A.[HU_VACANT] AS [r_HU_vac_ns],
do:
(A.[HU_VACANT] - A.[HU_VACANT_SEASONAL_RECREATIONAL])/NULLIF(A.[HU_VACANT], 0) AS [r_HU_vac_ns],

Instead of filtering out the records using
WHERE A.[HU_VACANT] > 0
You should filter out the records at root level
having SUM([ESTIMATE_1]) > 0
You could also use nullif function but that will result producing NULL where you have zero

Related

Case statement with division

I have case statement below as
count(CASE WHEN time_lag / 10000 >= 0 AND time_lag / 1000 <= 50 THEN 1 END) AS [0 - 50]
but am getting error on syntax error, is there proper way to divide in case statement? thanks
You need to add quotes to the desired column name (if it's not going to follow traditional naming rules.
Change:
select count(...) AS [0 - 50]
To:
select count(...) AS "[0 - 50]"
Btw, the exact syntax error you got was Syntax error: unexpected '['. (line 7). Please make sure to include the exact error you get in future posts.
Idenfitifers containing special characters have to be quoted with ". The query could be further simplified by using COUNT_IF:
select count_if(time_lag / 10000 >= 0 AND time_lag / 1000 <= 50) AS "[0 - 50]"
=>
select count_if(time_lag/1000 BETWEEN 0 AND 50) AS "[0 - 50]"
=>
-- no epxression on the column
select count_if(time_lag BETWEEN 0 AND 50*1000) AS "[0 - 50]"

Percentage of two values returning NULL

Same as yesterdays question which has been answered successfully but different problem. I have two values, 1 and 0 for which I need to calculate the percent change. Based on this website http://www.percent-change.com/index.php?y1=1&y2=0 the percent change between 1 and 0 is -100%. Based on the suggested formula which is (((y2- y1))/ y1) my code looks like this.
DefinedYearVSPriorYearIndividual = ((( CTEDefinedYear.IndividualCases - CTEPreviousYear.IndividualCasesLastYear ))
/ ( CTEPreviousYear.IndividualCasesLastYear ) ) * 100
which returns NULL.
The two numbers are
CTEDefinedYear.IndividualCases = 1
CTEPreviousYear.IndividualCasesLastYear = 0
The desired result should be -100%.
Can anybody see what I'm doing wrong?
Here is the answer.
Declare #y1 as int =1;
Declare #y2 as int =0;
select (((#y2- #y1))/ #y1)*100
Output is -100. You missed the *100 part.
In your case, You switched variables. attached formula is right one.
select ((0 - 1) / 1)*100;
But you used select ((1 - 0) / 0)*100;
so, you will get an error:
Msg 8134, Level 16, State 1, Line 1
Divide by zero error encountered.
You have to handle 0 in the division side, with CASE logic, to avoid divide by zero error.
DECLARE #CTEDefinedYear_IndividualCases INT = 1
DECLARE #CTEPreviousYear_IndividualCasesLastYear INT = 0
SELECT ((#CTEDefinedYear_IndividualCases - #CTEPreviousYear_IndividualCasesLastYear) / (CASE WHEN #CTEPreviousYear_IndividualCasesLastYear = 0 THEN 1 ELSE #CTEPreviousYear_IndividualCasesLastYear END)) * 100
Got it to work with this code.
DefinedYearVSPriorYearIndividual = ISNULL(100.0 *
(ISNULL(CTEDefinedYear.IndividualCases,0)
- ISNULL(CTEPreviousYear.IndividualCasesLastYear,0))
/ NULLIF(CTEPreviousYear.IndividualCasesLastYear,0),0)

Sql Case statement with value of 2+ columns greater than 1

I need to add the values in a row from three columns. When the value is greater than 1, it needs to populate a specific phrase.
So ... example
From temp_table_tx = count_of_x
From temp_table_ty = count_of_y
From temp_table_tz = count_of_z
I currently have the following, which only gives me an error.
CASE
WHEN (tx.count_of_x + ty.count_of_y + tz.count_of_z) >1 THEN 'Exception_present'
WHEN (tx.count_of_x + ty.count_of_y + tz.count_of_z) <1 THEN 'No_Exceptions'
ELSE 'error'
End As exceptions
You would get 'error' if any counts were NULL. So, this might fix your problem:
(CASE WHEN coalesce(tx.count_of_x, 0) + coalesce(ty.count_of_y, 0) + coalesce(tz.count_of_z, 0) > 1
THEN 'Exception_present'
WHEN coalesce(tx.count_of_x, 0) + coalesce(ty.count_of_y, 0) + coalesce(tz.count_of_z, 0) < 1 THEN 'No_Exceptions'
ELSE 'error'
END) As exceptions
It seems odd, though, that a count of exactly "1" would be considered an error.

Converting Access SQL to T-SQL

I have a created field in an Access database that I am trying to re-create in T-SQL. I am getting some incorrect results and I think it is how I wrote the code. Here is the field in Access that is working correctly:
MCP Actual: IIf([lever]="MCP",[actual usd]*IIf([split flag]="x",[split percent],1))*[Allocation Value]
Here is how I have it coded in SQL:
MCPActual =
CASE
WHEN pbd.Lever = 'MCP' THEN pbd.ActualUSD * CASE WHEN ou.SplitFlag = 'x' THEN ((pbd.ActualUSD * ou.SplitPercent) * pda.AllocationValue) END
ELSE ((pbd.ActualUSD * 1) * pda.AllocationValue)
END
I think you haven't got the END and brackets in the correct sequence try
CASE
WHEN pbd.Lever = 'MCP' THEN pbd.ActualUSD *
(CASE WHEN ou.SplitFlag = 'x' THEN
(pbd.ActualUSD * ou.SplitPercent * pda.AllocationValue )
ELSE
(pbd.ActualUSD * pda.AllocationValue) END)
END
You don't need to multiply by 1 unless you are trying to covert a negative / positive value.

Latitude and Longitude conversion error

I'm trying to execute a specific query in my database, but occurs the following error
Table San_Filial
Filial_Id Name lat lon
2 A -19.926131 -43.924373
3 B -19.952192 -43.938789
4 C -19.939626 -43.924541
5 D -19.95529 -43.92953
6 E -19.9099 -43.93124
7 F -19.926191 -43.946067
9 G -19.97125 -43.96622
14 H -19.89038 -43.921734
17 I -19.88838 -43.93059
19 J -19.94305 -43.94093
Query
SELECT *
FROM San_Filial
WHERE San_Filial.Credenciada_Id IN (2,3,4,5,6,7,9,14,17)
AND ACOS(COS(RADIANS(ltrim(San_Filial.lat)))
* COS(RADIANS(convert(float, -19.926131)))
* COS(RADIANS(ltrim(San_Filial.lon))
- RADIANS(convert(float, -43.924373)))
+ SIN(RADIANS(ltrim(San_Filial.lat)))
* SIN(RADIANS(convert(float, -19.926131)))) * 6380 < 5.0
Error
Mesage 8114, Level 16, State 5, Line 1
Error converting data type varchar to float.
Someone can help me ?
Start by seeing if you have any data that is not in a correct format:
select *
from san_filia1
wHERE San_Filial.Credenciada_Id IN (2,3,4,5,6,7,9,14,17) and
(isnumeric(lat) = 0 or isnumeric(long) = 0)
From this, you'll see what is causing the problem and then you can fix it.
The correct fix is probably along these lines:
select *
from (select sf.*,
(case when isnumeric(lat) then cast(lat as float) end) as latf,
(case when isnumeric(long) then cast(long as float) end) as longf
from san_filial sf
) sf
where . . . -- use Latf and Longf instead of lat and long
You need to do the conversion inside a case statement to guarantee that it works as expected. SQL does not guarantee the ordering of statements and a filter might be applied after the calculation.