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.
Related
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.
I'm getting a divide by zero error when performing the below code. I have tried a NULLIF after the ELSE, but I am encountering the same error message:
SELECT
country_IBS
, Sku
, LTM_Sales_USD
, PTM_Sales_USD
, LTM_Cost_USD
, (CASE WHEN -([LTM_Sales_USD]-[PTM_Sales_USD])/([LTM_Sales_USD]+[PTM_Sales_USD]) IS NULL
THEN 0
ELSE -([LTM_Sales_USD]-[PTM_Sales_USD])/([LTM_Sales_USD]+[PTM_Sales_USD]) END +1)/2 AS "Sales Growth % (scaled)"
FROM #tempSalesChange
Wrap the divider in the NULLIF:
{Expression 1} / NULLIF({Expression 2},0)
That will mean that if the divider is 0 then NULL will be returned, and the divide by zero error will be avoided.
In your case, that's ([LTM_Sales_USD]+[PTM_Sales_USD]).
If suspect that you want:
(1 - ([LTM_Sales_USD] - [PTM_Sales_USD]) / NULLIF([LTM_Sales_USD] + [PTM_Sales_USD], 0)
) / 2 AS [Sales Growth % (scaled)]
That is: the divisor should be wrap in NULLIF(..., 0). This avoids the division by zero error - in that case, the whole computation returns NULL instead.
I try to populate a result per col for each of the cast lines, but it gives me an error on each of the lines except the first one. If i just do the first one, it works as i want it too.
Why does it give me an error on the others even though the col names are existing in the referred view?
I tried just one cast line and thats working fine.
Select
cast ([sum nulls_shipment_id3] as float) / [count Total rows by carriername] *100 as [% NULL id3]
,cast ([sum nulls_shipment_id4] as float) / [count Total rows by carriername] *100 as [%null]
,cast ([EA/AH_REF] as float) / [count Total rows by carriername] *100
From dbo.BAS_CT_DATA_COMPLETENESS_vw1
Doesnt work (only if i remove the 2nd and 3rd cast formula)
If i run it with all three casts, the following error occurs:
Error:
Msg 207, Level 16, State 1, Line 4
Invalid column name 'sum nulls_shipment_id4'.
Msg 207, Level 16, State 1, Line 5
Invalid column name 'EA/AH_REF'.
cast ([sum nulls_shipment_id3] as float)
For the line above, the sum function is not being used correctly. Please fix into:
cast (sum([nulls_shipment_id3]) as float)
And the other problem is: here- > ,cast ([EA/AH_REF] as float), please use regular brackets instead of square ones like: ,cast ((EA/AH_REF) as float)
Ok i solved it, it also ran into error because on col name contained a "/", so renamed that and now it works...
Select
cast (nulls_shipment_id3 as float) / (Total_rows_by_carriername) *100 as [% NULL id3]
,cast (nulls_shipment_id4 as float) / (Total_rows_by_carriername) *100 as [%null]
,cast (nulls_EAAH_REF as float) / (Total_rows_by_carriername) *100 as [% NULLEAH]
From dbo.BAS_CT_DATA_COMPLETENESS_vw1
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
i am currently writing a scalar valued function and i'm having a few issue with the returned result.
i have narrowed the problem down to a calulation that convert the difference between two dates as a percentage/decimal. no matter what i try the return value is always a whole number
set #earnedpremium = (#premium * #pretripearnings) + ((#premium - (#premium * #pretripearnings)) * cast((datediff(day, #outdate, #experiencedate) / datediff(day, #outdate, #returndate))as decimal(5,2)))
the cast section needs to return the percentage, i know the rest is working fine through some elimination and testing.
can someone please help me figure out what im doing wrong??
It's because DATEDIFF returns an INTEGER and so you need to cast both parts of that operation to DECIMAL:
set #earnedpremium = (#premium * #pretripearnings) + ((#premium - (#premium * #pretripearnings))
* (CAST(datediff(day, #outdate, #experiencedate) AS DECIMAL(5,2)) /
CAST(datediff(day, #outdate, #returndate) AS DECIMAL(5,2)))