Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

Search

XML Feeds

Google Ads

« SQL Server 2008 Upgrade Technical Reference Guide Available For DownloadSQL Server Precision And Scale Problems »
comments
Rate Post:
submit to reddit Digg!FacebookDotnetkicks

There are various methods to accommodate this problem, let's examine a few of them and also check performance.

When you divide two numbers, and the denominator is 0, the result of the operation is undefined. In reality, we usually define some alternative number to use (usually 0). In the example and the code I show below, I will assume that the expected result for a 'divide by zero' condition is 0.

For most of us, the typical method for accommodating divide by zero is to first check the denominator to see if it is equal to zero. If it is, then return 0, otherwise perform the division. Like this…

  1. SELECT CASE WHEN Denominator = 0
  2.             THEN 0
  3.             ELSE Numerator/Denominator
  4.             END AS [CalculatedColumn]

Most programmers are very familiar with this syntax, and often times, it's the best way to approach the problem. However, there is another method that can be better under the right circumstances. The problem occurs when the denominator is a calculated value, and that calculation is slow.

  1. SELECT CASE WHEN dbo.SlowPerformingFunction() = 0
  2.             THEN 0
  3.             ELSE Numerator / dbo.SlowPerformingFunction()
  4.             END AS [CalculatedColumn]

In this case, the SlowPerformingFunction is evaluated twice, once in the test and again in the division. There is a way to write this query so that the function is only evaluated once. In order to understand this method, we need to know about other functions.

SQL Server has a NULLIF function. This function accepts 2 parameters. If the first parameter is equal to the second parameter, NULL is returned. Otherwise, the value in the first parameter is returned.

EX:

  1. SELECT NULLIF(0,0) -- Returns NULL
  2. SELECT NULLIF(7,0) -- Returns 7

Another handy function to know is COALESCE. Coalesce accepts multiple parameters. It checks each parameter and returns the first one that is NOT NULL. If all parameters are NULL, NULL is returned.
Ex:

  1. SELECT COALESCE(NULL, NULL, NULL, 'Apple') -- Returns Apple

Lastly, we need to think about the division. If you try to divide any number by zero, you will get an error. However, if you divide a number by NULL, you get NULL. We can use this to our advantage to prevent the 'divide by zero' error while evaluating slow performing functions just once. Like this:

  1. SELECT COALESCE(Numerator / NULLIF(dbo.SlowPerformingFunction(), 0), 0) AS [CalculatedColumn]

In this case, NULLIF will return the value from the SlowPerformingFunction if that value is not 0. If it is, NULLIF will return NULL. We then perform the calculation, and if the result is NULL, we replace it with 0 using the Coalesce function.

Is this method actually faster?

The true answer is, 'It depends'. If your denominator is a scalar value (parameter to the procedure or a pre-calculated value), then NO. The Case/When method can be faster. You see, if the denominator is zero, the division does not occur. However, if you have a poorly performing function, then the Coalesce/NullIf method will be faster because the function is called only once. Sure, the division occurs even if the result of the function is 0, but it's NULL math, and a simple division too.

My recommendation is to write the query both ways and compare the performance. Whichever method performs better is the one you should use.

About the Author

George has been developing software professionally for 19 years, first for the department of defense, and then for various other companies. In 1998, George started his software company, Orbit Software, specializing in School Bus Transportation software. His specialty is refining SQL Server queries to deliver optimal performance.
Social SitingsTwitterLTD RSS Feed
1954 views
submit to reddit Digg!FacebookDotnetkicks

Comments and Feedback

4 comments

Comment from: Suraj Shrestha [Visitor] Email · http://techcreeze.blogspot.com
***--

Hi,

I think its better to get the output of SlowPerformingFunction() in a
variable and use in case when statement.

After all, if it is matter about calling the function twice.
12/08/08 @ 10:07
Comment from: Gil Shayer [Visitor] Email
*****
Short and efficient !
I loved it !!!
12/11/08 @ 02:33
Comment from: sunil [Visitor]
*****
Beautiful!!!
04/22/09 @ 12:04
Comment from: sally attalla [Visitor]
****-
Thanks alot
it very usuful
06/10/09 @ 03:22

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)