アホすぎてSQLにおけるNULLの扱いが???ってなったので書く。
NULLと非NULLの比較
以下のテーブル Numbers があるとき。
A | B |
---|---|
1 | 200 |
3 | 100 |
NULL | 300 |
2 | 400 |
以下のSQLを実行する。
SELECT * FROM Numbers ORDER BY A ASC;
すると、以下のいずれかの結果が取得できる。
A | B |
---|---|
1 | 200 |
2 | 400 |
3 | 100 |
NULL | 300 |
A | B |
---|---|
NULL | 300 |
1 | 200 |
2 | 400 |
3 | 100 |
NULLを非NULL値より大きいとするか、小さいとするかは、DBMSの実装依存*1。
この問題に対処するため、SQL-99で NULLS (FIRST|LAST)
が追加された。
これはまあ常識として、ここからが本題。
NULLとNULLの比較
上記テーブルに A = NULL
な行を追加。
A | B |
---|---|
1 | 200 |
3 | 100 |
NULL | 300 |
2 | 400 |
NULL | 500 |
以下のSQLを実行する。
SELECT * FROM Numbers ORDER BY A, B ASC NULLS LAST;
結果は以下になる。
A | B |
---|---|
1 | 200 |
2 | 400 |
3 | 100 |
NULL | 300 |
NULL | 500 |
問題はここで、A = NULL
の2行の順序は保証されるか?
処理の流れとしては、「A列でソート→A列が等しい行をB列でソート」なので、順序が保証されるための前提条件は「2つの行のA列が等しい」。
一般にNULLとNULL及び非NULL値との比較は成り立たず、SQLにおいても SELECT NULL = NULL
の結果は当然FALSEになる*2。
なので、保証されないように思えるが、結論としては保証される。なんでか。
SQL-99において以下が定められているため。
A NULL is “equal” to a NULL for sorting purposes.
「ソートのときは同じってことでよろ」。ずるい。
ソート以外
ORDER BYだけでなく、GROUP BYやDISTINCTについてもNULLとNULLは等しいものとして扱われる。
GROUP BY NULL
ってやったらNULLでまとめてくれるのはなんとなく経験上で知ってるけど、よくよく考えたらなんで?ってなった。だってNULLですよ。標準でそう定義されてるからってやつ。「集約対同値性」問題と呼ばれたりするらしい。
ここまでも、まあ、常識。ここからがいよいよ本題。
本題
このところ、乾燥肌がつらい。
もともと乾燥肌というわけではなく、実際に昨年まではまったく問題がなかった。今季からつらい。加齢によるものと思われる。
ニベアクリームはすごい。
乾燥肌業界において、品質、価格、ブランディング等、比肩する商品が見当たらない。
だが、油分がすごい。
油分は肌から水分が蒸発するのを抑え、保湿効果を高める効能がある。一方で油分が多すぎる状態はアクネ菌の増殖を促し、ニキビを作る原因になってしまう。
参考
*1:PostgreSQL・DB2・Oracleは前者、SQL Server・MySQLは後者
*2:NULL is NULLはTRUE