3.15 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')
|