how to handle divide by zero error in sql - sql

cast(CAST(countAta AS float)
/ CAST(DATEDIFF(day,#searchDate,#EndDate) AS float) as decimal(16,2)
)

You can avoid such situations by setting the following parameters before your query and it should work just fine.
SET ARITHABORT OFF
SET ANSI_WARNINGS OFF
This would return a NULL when you do something like this: 123 / 0
The important point is to set these properties back ON once you are done with such operations. This particularly helps when you have complex queries in your Stored procedure and you don't want to end up writing more and more CASE statements to handle such a situation.

You should always use TRY-CATCH block and use the built-in error handling functions provided by SQL. Also, you can handle it in another way --
SELECT CASE
WHEN (CAST(DATEDIFF(Day, #searchDate, #EndDate) AS FLOAT) AS DECIMAL(16, 2)) = 0
THEN NULL -- Ideally it should return NULL but you can change it as per your requirement
ELSE CAST(CAST(Counter AS FLOAT) / CAST(DATEDIFF(Day, #searchDate, #EndDate) AS FLOAT) AS DECIMAL(16, 2))
END

The best way is NULLIF() . . . but you can't turn the value back into a 0:
select CAST(CAST(countAta AS float) /
NULLIF(DATEDIFF(day, #searchDate, #EndDate), 0
) as decimal(16, 2)
)
This returns NULL if the denominator is 0. Note that you don't have to cast to a float twice.

You could use NULLIF to avoid devided by zero error.
It returns NULL when denominator equals 0
CAST(countAta AS decimal(16,2)) /ISNULL(NULLIF(DATEDIFF(day,#searchDate,#EndDate),0), 1)
Or use CASE WHEN
CAST(countAta AS decimal(16,2)) /
CASE WHEN DATEDIFF(day,#searchDate,#EndDate) = 0 THEN 1
ELSE DATEDIFF(day,#searchDate,#EndDate)
END

Related

Divide Zero error when calculating Sales % in SQL

I keep getting the following error message:
Msg 8134, Level 16, State 1, Line 1 Divide by zero error encountered.
I've seen some posts about using IFNULL which I have tried.
For example:
,Case when a.DiscountReasonCode = 'RL' then IFNULL(((a.ORIGINALRETAIL-a.RetOne) / (a.ORIGINALRETAIL) * 100),0) end as [PctSB]
But this returns the following error:
'IFNULL' is not a recognized built-in function name.
What I'm doing is trying to calculate the proper sales percent and then find and compare it to what is already in the table to find errors or missing Sales %'s.
I'm not sure where I'm going wrong but any help would be greatly appreciated.
SELECT
a.packnum
,a.description
,a.CatID
,a.PctSavings
,Case when a.DiscountReasonCode = 'RL' then (a.ORIGINALRETAIL-a.RetOne) / (a.ORIGINALRETAIL) * 100
end as [PctSB]
FROM PIC704Current a Join CatalogInfo b ON (a.CatID = b.Catalog) and (a.Year = b.MailYear)
WHERE
b.MediaId in('CAT Catalog','SCAT Sale Catalog','SSTF Sale Statement Stuff','STUF Statement
Stuffer','PKG Package Insert','SPKG Sale Pkg Insert')
and a.DiscountReasonCode = 'RL'
and a.year >='2020'
and (Case when a.PctSavings <> (a.ORIGINALRETAIL-a.RetOne)/a.ORIGINALRETAIL*100 then 'False' else
'True' END) = 'False'
Thanks
Wrapping a divide in a null test will not get rid of the divide by 0 error. Instead, you need to check whether the value being divided by is 0 and return a different value instead. You can do this using IIF:
IIF(a.ORIGINALRETAIL = 0, 0, 100.0 * (a.ORIGINALRETAIL-a.RetOne) / a.ORIGINALRETAIL)
You can use coalesce or isnull . MySQL uses ifnull
case
when a.DiscountReasonCode = 'RL' then (a.ORIGINALRETAIL-a.RetOne) /
NULLIF(a.ORIGINALRETAIL, 0) * 100
end as [PctSB]
Msg 8134, Level 16, State 1, Line 1 Divide by zero error encountered.
This error suggests that your denominator is 0 so you can change it to NULL using a case expression.
'IFNULL' is not a recognized built-in function name.
In SQL Server , you can use ISNULL or Coalesce
CASE WHEN a.DiscountReasonCode = 'RL'
THEN ISNULL(((a.ORIGINALRETAIL-a.RetOne)/(CASE WHEN a.ORIGINALRETAIL = 0
THEN NULL
ELSE a.ORIGINALRETAIL
END) * 100),0)
END AS [PctSB]
I think the posts you've seen mentioning IFNULL might actually have been mentioning NULLIF, you just remembered it the wrong way round. One of the typical tricks to avoid a DIV/0 error in sqlserver:
some_number / NULLIF(other_number_maybe_zero, 0)
If the divisor is 0, it is converted to null, meaning the result is null rather than an error
In standard SQL you can do it too:
some_number / CASE WHEN other_number_maybe_zero = 0 THEN NULL ELSE other_number_maybe_zero END
It's just a bit more wordy
The logic that you want is provided by NULLIF():
(a.ORIGINALRETAIL - a.RetOne) * 100.0 / NULLIF(a.ORIGINALRETAIL, 0)) * 100) as [PctSB]
Using the standard SQL function NULLIF() is the simplest way to do what you want, and I recommend that you write the logic this way. It replaces any 0 value with NULL -- thereby avoiding the divide-by-zero.

how to use is null with case statements

Hi can any one say me how to write query in sql server management studio for statement =>if(isnull("GROSS_SF")=1 or "GROSS_SF"=0,0,"GROSS_SALES"/"GROSS_SF")
by using case statement :
CASE
WHEN ("GROSS_SF"=1 or "GROSS_SF"=0) isnull then 0
else "GROSS_SALES"/"GROSS_SF"
end/* i am getting error if i write it like this */
thanks in advance
If you want to avoid a divide by zero, while at the same time also handling NULL, then you may try the following logic:
CASE WHEN COALESCE(GROSS_SF, 0) = 0
THEN 0
ELSE GROSS_SALES / GROSS_SF END AS output
To be clear, the above logic would return a zero value should either the GROSS_SF be zero or NULL.
I think what are you looking for is IFNULL, look here https://www.w3schools.com/sql/sql_isnull.asp
You are close. You can do:
(CASE WHEN "GROSS_SF" IS NULL OR "GROSS_SF" = 0 THEN 0
ELSE "GROSS_SALES" / "GROSS_SF"
END)
In SQL, divide by zero errors are often avoided using NULLIF():
"GROSS_SALES" / NULLIF("GROSS_SF", 0)
However, that returns NULL rather than 0. If you really want zero:
COALESCE("GROSS_SALES" / NULLIF("GROSS_SF", 0), 0)
This is a bit shorter to write and almost equivalent to your version (this returns 0 if "GROSS_SALES" is NULL, which your version does not).
You can use NULLIF() to prevent arithmetic divide by zero errors :
select . . . ,
GROSS_SALES / nullif(GROSS_SF, 0)
from table t;
However, this would return null instead of error, if you want to display 0 instead then you need to use isnull() (MS SQL Specific) or coalesce() (SQL Standard).
So, you can express it :
select . . . ,
isnull(GROSS_SALES / nullif(GROSS_SF, 0), 0)
from table t;

An error in Null Value

Please help me out in this as im getting an error:
Divide by zero error encountered.
Warning: Null value is eliminated by an aggregate or other SET operation.
Here is the code:-
(CAST(SUM(ISNULL(Cur.CurAmount,0)) AS FLOAT) -
CAST(SUM(ISNULL(GLActualAmount,0)) AS FLOAT)) /
CAST(SUM(ISNULL(GLActualAmount,0)) AS FLOAT) * 100 GROWTH_AMT
I use NULLIF() in this situation:
(CAST(SUM(ISNULL(Cur.CurAmount,0)) AS FLOAT) -
CAST(SUM(ISNULL(GLActualAmount,0)) AS FLOAT)
) /
NULLIF(CAST(SUM(ISNULL(GLActualAmount,0)) AS FLOAT) * 100, 0) as GROWTH_AMT
Dividing by zero always gives an error. I would add WHERE ISNULL(GLActualAmount,0) <> 0) to the end of your query, since if GLActualAmount is zero, your result is meaningless.

Remove only zero after decimal sql server 2012

Consider the following numbers.
7870.2
8220.0
I need to remove decimal points if the value ends with .0. If it ends with .2 then it should keep the value as it is.
I have used ceiling but it removes all the values after decimal.
How can I write a select query in which I can add some condition for this?
Generally speaking you should not do this in your dB. This is an app or reporting side operation. The dB is made to store and query information. It is not made to format/string manipulate information.
use right within a case statement and:
DECLARE #val decimal(5,1)
SET #val = 7870.0
Select
Case
When right(#val,1)<> '0' then
cast(#val as varchar)
else
cast(cast(#val as int) as varchar)
End
output: 7870
EDIT: I could write :
Case
When right(#val,1)<> '0' then
#val
else
cast(#val as int) -- or floor(#val)
End
but because return type of case statement is the highest precedence type from the set of given types, so the output for second version is: 7870.0 not 7870, that's why I convert it to i.e varchar in when clauses, and it can be converted outside of case statement, I mean cast ((case when...then...else... end) as datatype)
Cast the number as a float, using float(24) to increase precision:
DECLARE #t table(number decimal(10,1))
INSERT #t values(7870.2),(8220.0)
SELECT cast(number as float(24))
FROM #t
Result:
7870,2
8220
Here below goes a sample:
declare #1 decimal(4,3)
select #1 = 2.9
select case when SUBSTRING (PARSENAME(#1,1), 1, 1) = 0 then FLOOR(#1) else #1 end
Change the #1 in the select statement with your database field name.
sqlfiddle
The solution seems to be simple:
SELECT CONVERT (FLOAT, PAYLOAD)

ACCESS Jet SQL INT() Function -> SQL Server Function

I am converting an Access Jet-SQL query into T-SQL and I came upon the Int() function. Now, I would like to convert it into T-SQL, and this is what I have so far:
--Works for Positive
Select CONVERT(INT, 1.2)
--Answer = 1
--Not the same as Access
SELECT CONVERT(INT, -1.2)
--Answer = -1
Now, according to this, I need it to return -2, not -1. Does anyone have cleaner T-SQL code than:
DECLARE #test FLOAT
SET #test = -1.2
SELECT CASE WHEN #test < 0 THEN CONVERT(INT, #test) - 1 ELSE CONVERT(INT, #test) END
Can anyone come up with cleaner code than this (T-SQL only)? No UDFs as this is an adhoc query. Thanks!
SELECT FLOOR(#test)
Oh yeah...
select convert(int, floor(#test))
Never mind...