| |
|
If this is your first visit, be sure to check out the FAQ by clicking the link above.
You may have to register before you can post: click the register link above to proceed.
To start viewing messages, select the forum that you want to visit from the selection below.
|
 |

02-08-12, 08:54
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 9
|
|
|
Division arithmetic - -801 22012 - Division by 0
|
|
Hi
I am struggling to get a statement working and wondering how I can get around it:
select (1 / (1/2)) from <table>;
Where in reality my sql is actually similar to
select (sum(capacity) / (count(deployments)/100)) as percentage from table;
I've tried casting to decfloat, dec, real but can't seem to get past this.. ?
Any ideas much appreciated!
Many thanks
|
|

02-08-12, 09:02
|
|
Super Moderator
|
|
Join Date: Aug 2001
Location: UK
Posts: 4,534
|
|
What is the result of
Code:
select count(deployments) from table
I would do something like (untested code)
Code:
case count(deployments)
when 0
then 0
else
(sum(capacity) / (count(deployments)/100))
end case
__________________
Visit the new-look IDUG Website , register to gain access to the excellent content.
|
|

02-08-12, 09:10
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 9
|
|
|
|
count(deployments) always returns a minimum of one.
In my code I actually have :
case when
count(deployments) = 0
then
0
else
(
case when
sum(capacity) = 0
then
0
else
(sum(capacity) / (count(deployments)/100))
end
)
end as percentage
and this is where I was getting the division by 0 problem.
So i've paired it back to the simplest part and came up with
select (1 / (1/2)) from table
as being able to cause an error.
If i do
select (1 /(1/1)) from table it works
If i do it in another DB it works aswell:
mysql> select (1 / (1/2));
+-------------+
| (1 / (1/2)) |
+-------------+
| 2.0000 |
+-------------+
1 row in set (0.02 sec)
It looks like because the 1/2 returns a number smaller than 1, it is dropping the numbers after the decimal place and just substituting 0.
Many thanks
|
|

02-08-12, 09:27
|
|
Registered User
|
|
Join Date: Jan 2003
Posts: 3,575
|
|
The arithmetic is INTEGER arithmetic. 1/2 using integers is 0. You need to convert each number to floating point before the division.
Andy
|
|

02-08-12, 09:29
|
|
:-)
|
|
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
|
|
You'll need to cast the division result [count(deployments)/100] to a non-integer datatype, otherwise it will get truncated to 0 if the result is less than 1. For example, [decimal(count(deployments))/100.]
|
|

02-08-12, 09:29
|
|
Registered User
|
|
Join Date: Feb 2008
Location: Japan
Posts: 2,195
|
|
Try
sum(capacity) / (NULLIF(count(deployments) , 0)/100.)
or
sum(capacity) * 100. / NULLIF(count(deployments) , 0)
Note: Affix dot(".") to 100.
Both would return NULL, if count(deployments) was 0.
If you want 0 in that case, use COALESCE.
COALESCE( sum(capacity) * 100. / NULLIF(count(deployments) , 0) , 0 )
|
|

02-08-12, 09:40
|
|
Registered User
|
|
Join Date: Feb 2008
Location: Japan
Posts: 2,195
|
|
If considered the precision of the result,
it would be better to use
sum(capacity) * 100. / NULLIF(count(deployments) , 0)
rather than
sum(capacity) / (NULLIF(count(deployments) , 0)/100.)
For example:
Code:
------------------------------ Commands Entered ------------------------------
DESCRIBE
VALUES 2 / ( NULLIF(10 , 0) / 100.);
------------------------------------------------------------------------------
Column Information
Number of columns: 1
SQL type Type length Column name Name length
-------------------- ----------- ------------------------------ -----------
485 DECIMAL 31, 0 1 1
------------------------------ Commands Entered ------------------------------
DESCRIBE
VALUES 2 * 100. / NULLIF(10 , 0);
------------------------------------------------------------------------------
Column Information
Number of columns: 1
SQL type Type length Column name Name length
-------------------- ----------- ------------------------------ -----------
485 DECIMAL 31,17 1 1
Code:
------------------------------ Commands Entered ------------------------------
VALUES 2 / ( NULLIF(10 , 0) / 100.);
------------------------------------------------------------------------------
1
---------------------------------
20.
1 record(s) selected.
------------------------------ Commands Entered ------------------------------
VALUES 2 * 100. / NULLIF(10 , 0);
------------------------------------------------------------------------------
1
---------------------------------
20.00000000000000000
1 record(s) selected.
|
Last edited by tonkuma; 02-08-12 at 09:44.
Reason: Add examples.
|

02-08-12, 10:02
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 9
|
|
many thanks to all.
where i had tried :
select double(1 / double(1/2)) from table
and still received the division by zero i've now got it working as
suggested with
select double(1) / (double(1) / double(2)) from table;
i.e. typecasting each number rather than the results.
Many thanks
|
|

02-08-12, 10:18
|
|
Registered User
|
|
Join Date: Feb 2008
Location: Japan
Posts: 2,195
|
|
Quote:
Originally Posted by niavasha
count(deployments) always returns a minimum of one.
In my code I actually have :
case when
count(deployments) = 0
then
0
else
(
case when
sum(capacity) = 0
then
0
else
(sum(capacity) / (count(deployments)/100))
end
)
end as percentage
and this is where I was getting the division by 0 problem.
|
If you tried my examples, all of the case expressions might be replaced by one of the expressions, like
COALESCE( sum(capacity) * 100. / NULLIF(count(deployments) , 0) , 0 ) as percentage
And, division by 0 problem would be avoided.
|
Last edited by tonkuma; 02-08-12 at 10:24.
Reason: Repeat one of the expressions.
|

02-08-12, 10:21
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 9
|
|
many thanks, I have now used your code in the end 
|
|

02-08-12, 20:17
|
|
Registered User
|
|
Join Date: Feb 2008
Location: Japan
Posts: 2,195
|
|
Although you might know and might use nested case expressions to avoid "Division by 0 problem".
Generally speaking, unnecessary nested case expressions should be avoided.
For example:
Quote:
case when
count(deployments) = 0
then
0
else
(
case when
sum(capacity) = 0
then
0
else
(sum(capacity) / (count(deployments)/100))
end
)
end as percentage
|
Note: I used the code as an example of nested case expressions.
(Actually, the case expressions might be avoided in your code, now.)
To be generalized, it would be written like...
Code:
CASE
WHEN <condition-1>
THEN <expression-1>
ELSE
(CASE
WHEN <condition-2>
THEN <expression-2>
ELSE <expression-3>
END
)
END AS column-name
It should be written like the following to avoild unnecessary complexity.
Code:
CASE
WHEN <condition-1>
THEN <expression-1>
WHEN <condition-2>
THEN <expression-2>
ELSE <expression-3>
END AS column-name
or, format like
Code:
CASE
WHEN <condition-1> THEN
<expression-1>
WHEN <condition-2> THEN
<expression-2>
ELSE <expression-3>
END AS column-name
Rationale:
Quote:
|
CASE expressions allow an expression to be selected based on the evaluation of one or more conditions. In general, the value of the case-expression is the value of the result-expression following the first (leftmost) case that evaluates to true. If no case evaluates to true and the ELSE keyword is present then the result is the value of the result-expression or NULL. ...
|
CASE expression - IBM DB2 9.7 for Linux, UNIX, and Windows
|
|

02-08-12, 22:25
|
|
Registered User
|
|
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,662
|
|
You could also use NULLIF():
Code:
SELECT ..., col1 / NULLIF(col2, 0)
FROM ...
That way, you don't have to write a CASE expression and you get a SQL NULL instead of a division-by-zero. Friendly arithmetics would also give you that if your version of DB2 supports this feature.
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|