Mapping NULL Values to Other Values for Display

3.15.1 Problem

A query's output includes NULL values, but you'd rather see something more meaningful, like "Unknown."

3.15.2 Solution

Convert NULL values selectively to another value when displaying them. You can also use this technique to catch divide-by-zero errors.

3.15.3 Discussion

Sometimes it's useful to display NULL values using some other distinctive value that has more meaning in the context of your application. If NULL id values in the taxpayer table mean "unknown," you can display that label by using IF( ) to map them onto the string Unknown:

mysql> SELECT name, IF(id IS NULL,'Unknown', id) AS 'id' FROM taxpayer; +---------+---------+ | name | id | +---------+---------+ | bernina | 198-48 | | bertha | Unknown | | ben | Unknown | | bill | 475-83 | +---------+---------+

Actually, this technique works for any kind of value, but it's especially useful with NULL values because they tend to be given a variety of meanings: unknown, missing, not yet determined, out of range, and so forth.

The query can be written more concisely using IFNULL( ), which tests its first argument and returns it if it's not NULL, or returns its second argument otherwise:

mysql> SELECT name, IFNULL(id,'Unknown') AS 'id' FROM taxpayer; +---------+---------+ | name | id | +---------+---------+ | bernina | 198-48 | | bertha | Unknown | | ben | Unknown | | bill | 475-83 | +---------+---------+

In other words, these two tests are equivalent:

IF(expr1 IS NOT NULL,expr1,expr2) IFNULL(expr1,expr2)

From a readability standpoint, IF( ) often is easier to understand than IFNULL( ). From a computational perspective, IFNULL( ) is more efficient because expr1 never need be evaluated twice, as sometimes happens with IF( ).

IF( ) and IFNULL( ) are especially useful for catching divide-by-zero operations and mapping them onto something else. For example, batting averages for baseball players are calculated as the ratio of hits to at-bats. But if a player has no at-bats, the ratio is undefined:

mysql> SET @hits = 0, @atbats = 0; mysql> SELECT @hits, @atbats, @hits/@atbats AS 'batting average'; +-------+---------+-----------------+ | @hits | @atbats | batting average | +-------+---------+-----------------+ | 0 | 0 | NULL | +-------+---------+-----------------+

To handle that case by displaying zero, do this:

mysql> SET @hits = 0, @atbats = 0; mysql> SELECT @hits, @atbats, IFNULL(@hits/@atbats,0) AS 'batting average'; +-------+---------+-----------------+ | @hits | @atbats | batting average | +-------+---------+-----------------+ | 0 | 0 | 0 | +-------+---------+-----------------+

Earned run average calculations for a pitcher with no innings pitched can be treated the same way. Other common uses for this idiom are as follows:

IFNULL(expr,'Missing') IFNULL(expr,'N/A') IFNULL(expr,'Unknown')

Категории