新人SEのためのSQL NULL
SQLでややこしくて、よく理解しないまま過ごしてしまいがちなのがNULLではないでしょうか? しかも、DBMSによっても微妙に違いますので、尚更注意が必要です。
きっちり、NULLを押さえましょう!
押さえるべきポイントは以下の4つ。
1.NULLは、何を足しても、引いても、掛けても、割ってNULL
2.NULLには、=や<>、<、>は通用しない
3.NULLはIS NULL か IS NOT NULLで判定するかNULLを扱える
関数を使用する
4.CASE文でNULLを使う時は注意せよ。
5.NULLは’’(長さゼロの文字値)とは違う。
でも、Oracleは「’’」とNULLは同じ
ここではOracleを使って説明します。
1.NULLは、何を足しても、引いても、掛けても、割ってNULL
そうなのです。そしてエラーにもなりません。
以下のSQL文を実行してみてください。
SELECT NULL+1 , NULL-1 , NULL*1 , NULL/1 , LEHGTH(NULL) FROM DUAL;
答えは全てNULLです。
ただし、SUMやCOUNTの場合は集計している中にNULLの行があっても、そのデータが加算されないだけで結果がNULLにはなりません。
興味のある方は、以下も試してみてください。
SELECT COUNT(*) FROM ( SELECT NULL FROM DUAL);
/* 答えは1 */
SELECT COUNT(col) FROM ( SELECT NULL AS col FROM DUAL);
/* 答えは0 */
SELECT SUM(col) FROM ( SELECT NULL AS col FROM DUAL);
/* 答えはNULL */
SELECT COUNT(*) FROM
( SELECT NULL FROM DUAL UNION ALL
SELECT NULL FROM DUAL );
/* 答えは2 */
SELECT COUNT(col) FROM
( SELECT NULL AS col FROM DUAL UNION ALL
SELECT 1 FROM DUAL);
/* 答えは1 */
SELECT SUM(col) FROM
( SELECT NULL AS col FROM DUAL UNION ALL
SELECT 1 FROM DUAL);
/* 答えは1 */
また、NULLには長さもありません。
LENGTH(NULL)は、ゼロではなく、NULLです。
2.NULLには、=や<>、<、>は通用しない
以下を実行してみてください。
SELECT 1 FROM DUAL WHERE NULL > 1;
SELECT 1 FROM DUAL WHERE NULL < 1;
SELECT 1 FROM DUAL WHERE NULL = 1;
SELECT 1 FROM DUAL WHERE NULL <> 1;
上記はいずれも、
>レコードが選択されませんでした。
となります。
試しに、以下も同じです。
SELECT 1 FROM DUAL WHERE NULL = NULL;
NULL とNULLは同じですが、成立しないのです。
3.NULLはIS NULL か IS NOT NULLで判定するか、NULLを扱える関数を使用する
NULLは
IS NULL または、IS NOT NULL
で判定します。
SELECT 1 FROM DUAL WHERE NULL IS NULL ;
SELECT 1 FROM DUAL WHERE 1 IS NOT NULL ;
上記はいずれもTRUEとなります。
IS NULL、IS NOT NULL以外だと、NULLを判定できるいくつかの関数があります。
DECODE、NVL、IFNULL、CASEなど。(DBMSによって異なります)
4.CASE文でNULLを使う時は注意せよ。
CASE文には2種類の書き方があります。
SELECT CASE 1 WHEN 1 THEN '1です' ELSE '1ではないです' END FROM DUAL;
SELECT CASE WHEN 1 = 1 THEN '1です' ELSE '1ではないです' END FROM DUAL;
上記はいずれも同じ結果となります。
しかし、これをNULLに置き換えると結果は違ってきます。
SELECT CASE NULL WHEN NULL THEN 'NULLです' ELSE 'NULLではないです' END FROM DUAL;
SELECT CASE WHEN NULL IS NULL THEN 'NULLです' ELSE 'NULLではないです' END FROM DUAL;
上のSQLは、"NULLではない"を返します。エラーにもなりません。
気を付けましょう。
5.NULLは「''」とは違う。
でも、Oracleは「''」とNULLは同じ
一般には、NULLと「''」は異なります。しかし、Oracleは「''」はNULLになります。くれぐれも注意してください。
/*Oracleの場合*/
SELECT CASE WHEN '' IS NULL THEN 'NULLです' ELSE 'NULLではないです' END FROM DUAL;
/*MySQLの場合*/
SELECT CASE WHEN '' IS NULL THEN 'NULLです' ELSE 'NULLではないです' END ;
Oracleは、"NULLです"が返り、MySQLは"NULLではないです"が返ります。
これは、くれぐれも注意してください。
また、LENGTH(NULL)は、NULLですが、「''」はOracleとMySQLで異なります。
/*Oracleの場合*/
SELECT LENGTH('') FROM DUAL;
/*MySQLの場合*/
SELECT LENGTH('');
OracleはNULLが返り、MySQLは0が返ります。
という事で、皆様、NULLには十分気を付けてください。