SQL ISZERO() And NULLIF() For Dividing By Zero

Posted January 15, 2007 at 3:23 PM by Ben Nadel

Tags: SQL

I am working on writing a bunch of SQL reports that have a lot of SQL aggregates. One of the computations that comes up a lot is the figuring out of percentages. To this, as you all know, you have to divide one number by another number and of course the number on the bottom cannot be Zero.

Since many of these bottom numbers are aggregates (thing SQL SUM(), MAX(), MIN()), I don't want to call them too often. What I want is something that works like the SQL function ISNULL(), where you can pass in a value just once. So, I wrote a quick little function called ISZERO():

  • CREATE FUNCTION IsZero (
  • @Number FLOAT,
  • @IsZeroNumber FLOAT
  • )
  • RETURNS FLOAT
  • AS
  • BEGIN
  •  
  • IF (@Number = 0)
  • BEGIN
  • SET @Number = @IsZeroNumber
  • END
  •  
  • RETURN (@Number)
  •  
  • END

This simply checks the passed in number to see if it Zero. If it is, then I just pass back the alternate number. If is not Zero, then I pass back the original value. This allows me to pass in computational-heavy numbers without having to compute them more than once.

  • (
  • CAST( SUM( r.price ) AS FLOAT ) /
  • (
  • SELECT
  • dbo.ISZERO( SUM( r2.price ), 1 )
  • FROM
  • reward r2
  • INNER JOIN
  • [order] o2
  • ON
  • r2.order_id = o2.id
  • WHERE
  • o2.user_id = u.id
  • ) *
  • 100
  • ) AS percentage_used

Notice that I only have to run the SUM() aggregate once (for each value).

What's also nice about this is that it converts the passed-in numbers to FLOAT automatically which saves me having to do it on the other end of things. This is great as all of the reporting values require FLOAT values.

After I wrote this, it occurred to me that this is probably a VERY common problem. So, I did some Google searches to see how other people have dealt with this. Doing so, I came across a very cool function named NULLIF(). This function returns a NULL if the two passed-in arguments are the same value. That can be super useful.

You could accomplish the ISZERO() method using NULLIF() this way:

  • (
  • CAST( SUM( r.price ) AS FLOAT ) /
  • ISNULL(
  • NULLIF(
  • (
  • SELECT
  • SUM( r2.price )
  • FROM
  • reward r2
  • INNER JOIN
  • [order] o2
  • ON
  • r2.order_id = o2.id
  • WHERE
  • o2.user_id = u.id
  • ),
  • 0
  • ),
  • 1
  • ) *
  • 100
  • ) AS percentage_used

This works fine, but is just a bit too wordy for my taste. But certainly, NULLIF() is a great function to have under the belt.



Reader Comments

Jan 15, 2007 at 3:37 PM // reply »
48 Comments

I do it the lazy mans way:

CASE when denominator = 0
then 0
else numerator/denominator end as result

Did I use those terms correctly? I suck at math, but I think you get the picture.


Jan 15, 2007 at 4:54 PM // reply »
1 Comments

Or, you can take the REALLY lazy way out:

<cfif not isNumeric(qryGraphData_total.t_avg)>
<cfset t_avg = 0>
<cfelse>
<cfset t_avg = qryGraphData_total.t_avg>
</cfif>


Jan 15, 2007 at 4:54 PM // reply »
6 Comments

Or, you can take the REALLY lazy way out:

<cfif not isNumeric(qryGraphData_total.t_avg)>
<cfset t_avg = 0>
<cfelse>
<cfset t_avg = qryGraphData_total.t_avg>
</cfif>


Jan 16, 2007 at 7:32 AM // reply »
11,232 Comments

@Todd,

That is how I would do it if the value that I was testing was a simple value, but in my case, I was testing an aggregate which has a lot of processing to it:

CASE
WHEN SUM( r.price ) = 0
THEN 1
ELSE SUM( r.price )
END

I would have to run the SUM() aggregate twice which is what I want to avoid doing.

@Peter,

That is how I would do it in ColdFusion, but I needed to do all this in the actual SQL statement as I needed to pass this query result off to a report generator. I could have updated the query after it was executed (which is actually what I was doing originally), but then I felt that I could accomplish the same thing faster by tightening up my SQL.


Sep 28, 2010 at 4:48 AM // reply »
2 Comments

hi.. thanks a lot

this blog helped as i was doing the dynamic query.

thanks
Yogaa Kapadia


Sep 28, 2010 at 4:49 AM // reply »
2 Comments

hi.. thanks a lot

this blog helped as i was doing the dynamic query.

thanks
Yogaa Kapadia


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools