Oracle Error when dividing by Zero - sql

I have a query where I need to get a certain number divided by 2 fields in 2 columns.
shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7) as Shelve_DOC
I get the notorious error.
ORA-01476: divisor is equal to zero
01476. 00000 - "divisor is equal to zero"
*Cause:
*Action:
I have read around I need a CASE/IF but I'm not sure how to..
Any help would be appreciated.

SELECT
CASE WHEN (GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7) = 0 THEN null
ELSE shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7)
END Shelve_DOC
FROM ...
WHERE ....
Should do the trick.

Something like this?
CASE WHEN NVL(y.FORECAST_QUANTITY,0) <= 0 AND NVL(z.sales,0) <= 0
THEN NULL
ELSE shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7)
END AS Shelve_DOC

Related

ORA-01722: invalid number - getting this error

I am trying to execute below in oracle sql developer
select code, case when (code = 'SS') then 1 else to_number(code) end as code_modified
from pxrptuser.WBS
But I am getting error.
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The output should be -
code code_modified
D0DV-IMS null
gWBS null
8 8
1 1
SS 1
Please help me with the actual query
You have strings in your data that cannot be converted to numbers (other than "SS").
Starting Oracle 12.2, you can use the on conversion error clause to to_number() to return null for invalid values:
select code,
case
when code = 'SS' then 1
else to_number(code default null on conversion error)
end as code_modified
from pxrptuser.WBS
In earlier versions, one alternative uses a regex. If your numbers have no decimal part, as showned in your data, it is simpler:
select code,
case
when code = 'SS' then 1
when not regexp_like(code, '\D') then to_number(code)
end as code_modified
from pxrptuser.WBS

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 have 3 conditions to fulfill in CASE WHEN in SQL

I am having difficulty when trying to have 3 conditions to fulfill in CASE WHEN in SQL server. Here is my original script but only return value 0 instead of 1 and 0. My purpose is to check when a customer purchase ITEM_01 with more than or equal to 0.06 AND ITEM_02 with more than or equal to 0.06 THEN return value 1 else 0. Here is my script:
CASE WHEN SUM ( CASE WHEN ITEM_01)='DH' AND (ITEM_02)='DH Classic' THEN NVL
(SALE_OUTLETD.PRE_SALES_QTY * SKU_UOM_CONV.MULTIPLIER,0) + NVL
(SALE_OUTLETD.SALES_QTY * SKU_UOM_CONV.MULTIPLIER, 0) -NVL
(SALE_OUTLETD.FRESH_RTN_QTY *SKU_UOM_CONV.MULTIPLIER, 0) - NVL
(SALE_OUTLETD.OLD_RTN_QTY * SKU_UOM_CONV.MULTIPLIER,0) - NVL
(SALE_OUTLETD.DAMAGED_RTN_QTY *SKU_UOM_CONV.MULTIPLIER, 0) - NVL
(SALE_OUTLETD.WITHDRAWAL_RTN_QTY *SKU_UOM_CONV.MULTIPLIER, 0) ELSE 0 END )
>= 0.06 THEN 1 ELSE 0 END 3_PACK_AND_ABOVE
Please help on this question because I have been stuck for few hours now. Any help would be greatly appreciated!
I am finding your example impossible to read but the basic form of CASE is:
select case WHEN first_boolean THEN first_value
WHEN second_boolean THEN second_value
WHEN third_boolean THEN third_value
...
ELSE default_value
Always try to build things off that model. Nested CASE statements like what you are doing are never fun and tend to be fairly error prone.

Invalid number error in where clause

I am executing a query in Oracle database. The column and everything is correct but I am getting an Invalid Number error for below query:
select COUNT(*) AS "COUNT" from NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
and TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4)) < 6000;
NET_ENTITY_ID field has only one data ABCDEFGHXXXXNB0001.
But not necessary that it will always be having one data. This is just for resolving the issue I am considering only this.
Error Message:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The problem is that Oracle -- and any other database -- does not guarantee the order of evaluation of clauses in a WHERE. You can get around this using CASE:
where B.STRUCT_TYPE in ('IDC') and
NET_ENTITY_ID is not null and
length(NET_ENTITY_ID) = 18 AND
regexp_like(SUBSTR(NET_ENTITY_ID, 15, 1), '[^A-Z]') and
(CASE WHEN regexp_like(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4), '^[0-9]{4}$'
THEN TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4))
END) < 6000;
You need to ensure that the last 4 chars are numeric before using TO_NUMBER on them.
This will do it:
select COUNT(*) AS "COUNT" from
( SELECT * FROM NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
AND regexp_like(SUBSTR(NET_ENTITY_ID,-4),'[0-9]')
)
where TO_NUMBER(SUBSTR(NET_ENTITY_ID,-4)) < 6000;
NB I simplified your SUBSTR for obtaining the last 4 characters.

Using COALESCE in oracle and getting ORA-00907: missing right parenthesis

I am trying to use COALESCE function in query but it throws an error ORA-00907: missing right parenthesis but the same query is running well in mysql i dont know how to write same query in orcale please help me out from this error.
SELECT DISTINCT sut.SERVICE_USER_TYPE , COUNT(er.ENFORCMENT_ID)
, SUM(er.FINE_AMOUNT),
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
from SERVICE_USER_TYPE sut
LEFT JOIN SERVICE_USERS su
ON su.SERVICE_USER_TYPE_ID = sut.SERVICE_USER_TYPE_ID
LEFT JOIN ENFORCEMENT_REPORT er ON su.SERVICE_USER_ID = er.SERVICE_USER_ID
group by sut.SERVICE_USER_TYPE ;
and the error
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 4 Column: 23
please help me out..
You say this works in MySQL. Well, the COALESCE expression results in 0, 1 or NULL per record. Then you aggregate your rows, but there is no aggregate on your COALESCE expression. This gives you a random 0, 1 or NULL per SERVICE_USER_TYPE.
The COALESCE expression
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
does the following in MySQL (only obfuscated):
CASE
WHEN er.CHECK_DATE IS NULL THEN NULL
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
or, with NULL being the default, shortly
CASE
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
You can do the same in Oracle and any other DBMS, but think about what aggregate you want to see. (If you expect it to be the same within all records for a SERVICE_USER_TYPE, use MIN or MAX or AVG, whichever you like best.)
For instance:
MIN
(
CASE
WHEN er.CHECK_DATE >= DATE'2015-01-12' THEN 1
WHEN er.CHECK_DATE < DATE'2015-01-12' THEN 0
END
)