ホームページ >データベース >mysql チュートリアル >SQL での Null の解析
コンピューターやプログラミングの世界におけるNULLは、未知、不確実という意味です。漢訳では「空」ですが、この空(ヌル)はそれほど空(空)ではありません。 Null は未知の状態、つまり将来の状態を表します。たとえば、Xiao Ming がポケットにいくら持っているかはわかりませんが、それが 0 であるかどうかはわかりません。現時点では、Null はコンピュータで表すために使用されます。未知で不確実。
SQL に精通している人は Null について何の疑問も持たないでしょうが、それを包括的にまとめた記事を見つけるのはまだ困難です。英語版を見たので、かなり良いと思いました。
Tony Hoare は 1965 年に null を発明しました引用、そしてそれが彼が犯した「10 億ドルの間違い」であると考えましたが、50 年後の今日でも、SQL の null 値は依然として多くの一般的なエラーを引き起こします。最も衝撃的な状況を見てください。
Null はサイズ/等価性の判断をサポートしていません次の 2 つのクエリでは、users テーブルにレコードがいくつあっても、返されるレコードは 0 行になります:
select * from users where deleted_at = null; – result: 0 rows select * from users where deleted_at != null; – result: 0 rows
これはすべて、null が意味するためです。 「不明」タイプ。つまり、通常の条件演算子を使用して null を他の値と比較することは意味がありません。 Null は Null と等しくありません (おおよその理解: 未知の値が未知の値と等しくなることはあり得ず、この 2 つの値の間の関係も不明です。そうでないと数学と論理が台無しになります)。
– 注: 次の SQL は
MySQL に適しています。Oracle の場合は、... from Dual;select null > 0;
– result: null
select null < 0;
– result: null
select null = 0;
– result: null
select null = null;
– result: null
select null != null;
– result: null
を追加する必要があります。値を null と比較する正しい方法は、is キーワードを使用することです、そして is not 演算子:select * from users
where deleted_at is null;
– result: 所有被标记为删除的 users
2 つの列の値が異なるかどうかを判断したい場合は、 isdistinct from:
select * from users where has_address is distinct from has_photo – result: 地址(address)或照片(photo)两者只有其一的用户not in と Null
サブクエリ (subselect) は非常に便利です。便利なデータフィルターメソッド。たとえば、パッケージを持たないユーザーにクエリを実行したい場合は、次のようなクエリを作成できます:
select * from users where id not in (select user_id from packages)
ただし、このとき、packages テーブルの行の user_id が null の場合、問題が発生します。返された結果は空です! なぜこの奇妙なことが起こるのかを理解するには、SQL コンパイラーが何をするのかを理解する必要があります。より簡単な例を次に示します: select * from users
where id not in (1, 2, null)
この SQL ステートメントは次のように変換されます:
select * from users where id != 1 and id != 2 and id != null
id != であることがわかります。 null 結果は不明な値、null です。任意の値と null の間の AND 演算の結果は null なので、他の条件と同等ではありません。この結果の理由は、null の論理値が true ではないためです。
条件が逆の場合はクエリ結果に問題はありません。 次に、パッケージを使用してユーザーにクエリを実行します。
select * from users where id in (select user_id from packages)
同様に、簡単な例を使用できます:
select * from users where id in (1, 2, null)
この SQL は次のように変換されます:
select * from users where id = 1 or id = 2 or id = null
where 句は一連の or 条件であるため、そのうちの 1 つの結果は null になります。も無関係です。 true 以外の値は節の他の部分の計算結果に影響を与えず、無視されるのと同等です。
Null とソートソートの際、Null 値が最大であるとみなされ、降順 (降順) でソートする場合、Null 値が最初にランク付けされるため、これでは頭が痛くなります。 次のクエリはスコアに基づいてユーザーのランキングを表示することですが、スコアのないユーザーを上位にランク付けします!
select name, points from users order by 2 desc; – points 为 null 的记录排在所有记录之前!
この種の問題を解決するには 2 つのアイデアがあります。最も簡単な方法は、Coalesce を使用して null の影響を排除することです:
– 在输出时将 null 转换为 0 : select name, coalesce(points, 0) from users order by 2 desc; – 输出时保留 null, 但排序时转换为 0 : select name, points from users order by coalesce(points, 0) desc;
ソート時に null 値を先頭に置くか最後に置くかを指定する、データベース サポートを必要とする別の方法があります:
select name, coalesce(points, 0) from users order by 2 desc nulls last;
もちろん、nullゼロで除算する算術演算を処理する場合など、エラーの発生を防ぐためにも使用できます。
0による除算 0による除算は、非常に痛ましいエラーです。昨日は正常に動作していた SQL が、0 で割ると突然異常が発生しました。一般的な解決策は、最初に case ステートメントを使用して分母が 0 かどうかを判断し、次に除算演算を実行することです。 select case when num_users = 0 then 0
else total_sales/num_users end;
ase文の使い方が実に醜く、分母が使い回されています。単純な状況であれば問題ありませんが、分母が非常に複雑な
の場合は、悲劇が起こります。読みにくく、保守や変更も難しく、注意しないと、たくさんのバグがあります
この時点で、null の利点を見てみましょう。nullif を使用して、分母が 0 の場合に null になります。このようにして、num_users = 0 の場合、返される結果は報告されません。 nullになります。select total_sales/nullif(num_users, 0);
nullif 是将其他值转为 null, 而Oracle的 nvl 是将 null 转换为其他值。
nullは望まないが、0や他の数値に変換したい場合は、前のSQLに基づいてcoalesce関数を使用できます:
select coalesce(total_sales/nullif(num_users, 0), 0); null 再转换回0結論
トニー・ホアは自分の間違いを後悔するかもしれないが、少なくともヌルの問題は簡単に解決できるので、新しい究極の技を練習し、ヌル(無効化)によって掘られた効果のない穴から離れてください!
以上がSQL での Null の解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。