PDA

View Full Version : MySQL Query error - Divide By Zero workaround?


tom92909
04-24-2009, 08:02 AM
I didn't really know where to place this new thread. It's data related, so I picked DataAssist.

Anyway, I have a query for MySQL that I am trying to obtain a percentage change from one years total sales to another years total sales on each item record. Some of the records have zeros in the calculation fields, which causes a huge problem by crashing the query with a Divide by Zero error.

Query Example:

SELECT *,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,
SUM ( `TotalUnits` - `inventory.Year1qty` ) / `TotalUnits` AS Percent
FROM `inventory`
WHERE `Dept` = 'WIDGETS'
GROUP BY Item

Is there a work around for this that I just haven't figured out? I assume this is a common MySQL issue with many more folks than just myself...

Ray Borduin
04-24-2009, 08:57 AM
SELECT *,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,

IF(`TotalUnits`=0,0,SUM ( `TotalUnits` - `inventory.Year1qty` ) / `TotalUnits`) AS Percent

FROM `inventory`
WHERE `Dept` = 'WIDGETS'
GROUP BY Item

tom92909
04-24-2009, 09:14 AM
Error Message...
MySQL said: Documentation
#1054 - Unknown column 'TotalUnits' in 'field list'


SELECT * ,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,
IF( `TotalUnits` =0, 0, SUM( `TotalUnits` - `inventory.Year1qty` ) / `TotalUnits` ) AS Percent
FROM `inventory`
WHERE `Dept` = 'WIDGET'
GROUP BY Item
ORDER BY Brand ASC

Ray Borduin
04-24-2009, 09:16 AM
SELECT * ,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,
IF( SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) =0, 0, SUM( SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) - `inventory.Year1qty` ) / SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) ) AS Percent
FROM `inventory`
WHERE `Dept` = 'WIDGET'
GROUP BY Item
ORDER BY Brand ASC

tom92909
04-24-2009, 09:28 AM
Error Message...

#1111 - Invalid use of group function

tom92909
04-24-2009, 09:42 AM
What about something like this....

SELECT * , SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits, (
ISNULL( (
(
`Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits`
) - `Year1qty` ) / NULLIF( `Year1qty` , 0 )
)
)

With the above, I'm getting the query to pass, but I'm getting 1's for good data only and zeros for the records that had denominators as zero (which is fine), but the records that can be calculated I need the accurate calculation to show up, not just a one.

Any suggestions?

Ray Borduin
04-24-2009, 10:02 AM
SELECT *,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,
SUM ( `TotalUnits` - `inventory.Year1qty` ) / `inventory.Year1qty` AS Percent
FROM `inventory`
WHERE `Dept` = 'WIDGETS'
GROUP BY Item

didn't you want to use `inventory.Year1qty` anyway for percent? It appears you wouldn't ever have devide by zero at that point.

Another observation... the last error you got was an error in the GROUP BY.

Does the query:


SELECT *,
SUM( `Janunits` + `Febunits` + `Marunits` + `Aprunits` + `Mayunits` + `Jununits` + `Julunits` + `Augunits` + `Sepunits` + `Octunits` + `Novunits` + `Decunits` ) AS TotalUnits,
SUM ( `TotalUnits` - `inventory.Year1qty` ) AS PercentTop, `TotalUnits` AS PercentDivide
FROM `inventory`
WHERE `Dept` = 'WIDGETS'
GROUP BY Item

return what you expect?

tom92909
06-26-2009, 11:25 AM
I took about 2 months off on this problem, and now I'm back to try and find a solution for a work around for "divide by zero" errors. I have the following that I'm working on (same as before mostly)...

SUM( Janunits + Febunits + Marunits + Aprunits + Mayunits + Jununits + Julunits + Augunits + Sepunits + Octunits + Novunits + Decunits ) AS CurrentTotal


It is possible that some of the records might have ZERO across all of the above fields.

Then I need to subtract the difference of the CurrentTotal from the PreviousTotal (previous total from the year before).

CurrentTotal - PreviousTotal = Difference


Once I have the difference amount, I then need to take that amount and divide it by the CurrentTotal and then multiply that result by 100

(Difference / CurrentTotal)*100 = PercentageDifference


Ok, so in the example above, there are a few of the rows that appear not to have had any activity over the past year. Resulting in a fatal Divide By Zero error message. Due to accounting restrictions, I can not filter out these rows, they must remain in the result set. I'm hoping for a solution to bypass the fatal error.

Any suggestions?

Ray Borduin
06-29-2009, 09:13 AM
Maybe try using something like:

SUM( Janunits + Febunits + Marunits + Aprunits + Mayunits + Jununits + Julunits + Augunits + Sepunits + Octunits + Novunits + Decunits ) + 0.000000001 AS CurrentTotal

and

Round((Difference / (CurrentTotal - 0.000000001))*100,2) = PercentageDifference

By adding an insignificant number to the result you can prevent ever dividing by zero without throwing off your calculation by more than would be significant after dividing.