MySQLでNULL値を判定する際の落とし穴事例

MySQLでNULL値を判定する際の落とし穴事例

序文

今日、プログラムを開発しているときに、case when 構文を使用して MySQL からデータを抽出し、判断しました。使用中に、NULL 値の判断時に小さな問題が発生しました。

MySQL の when 文は Java の switch 文に似ており、より柔軟ですが、MySQL での Null の処理は少し特殊です。

Mysql の case when 構文:

構文1:

CASE ケース値
    WHEN when_value THEN ステートメントリスト
    [WHEN when_value THEN statement_list] ...
    [ELSE ステートメントリスト]
終了ケース

構文2:

場合
    WHEN 検索条件 THEN ステートメントリスト
    [WHEN 検索条件 THEN ステートメント リスト] ...
    [ELSE ステートメントリスト]
終了ケース

注: これら 2 つの構文には違いがあり、その違いは次のとおりです。

1: 最初の構文: case_value は、userid%2=1 や username is null などの式である必要があります。この構文は NULL のテストには使用できません。

2: 2 番目の構文 CASE には変数や式は必要ありません。直接実行すると、各 WHEN の後の条件が評価され、条件が満たされた場合に実行されます。

事例実践:

テーブル構造は次のようになります: aの値はnull、bの値は1です

mysql> SELECT NULL AS a, 1 AS b;
+------+---+
| ア | ロ |
+------+---+
| NULL | 1 |
+------+---+

ここで、aの値がnullの場合はbの値を取得し、そうでない場合はaの値を取得するように実装します。

方法1: ifnullの使用

選択
    IFNULL(a, b) 新規、
    、
    b
から
    -- 一時テーブルを作成します。a の値は null、b の値は 1 です。
    (NULL を a として、1 を b として選択) tmp;

方法2: 使用する場合

選択
    (
        場合
        aがNULLの場合
            b
        それ以外
            1つの
        終わり
    ) 新品同様、
    、
    b
から
    (NULL を a として、1 を b として選択) tmp;

結果が間違っていることがわかりました。new の値は、期待どおり 1 ではなく null でした。

このエラーはなぜ発生するのでしょうか?これは、最初の構文と 2 番目の構文が混在していることが原因です。case 後の Commission_pct には、実数値または null の 2 つの値があり、commission_pct が null の場合も true または false の 2 つの値があります。したがって、case 後の値が null の場合、true または false と一致することはなく、出力は null ではありません。

この場合に構文 1 を使用する必要がある場合は、次のように書き直すことができます。

選択
    (
        ケースaはNULLです
        TRUEの場合、b
        それ以外         
        終わり
    ) 新品同様、
    、
    b
から
    (NULL を a として、1 を b として選択) tmp;

構文 2 を使用して次のように記述することもできます。

選択
    (
        場合
        aがNULLの場合、b 
        それ以外 
        終わり
    ) 新品同様、
    、
    b
から
    (NULL を a として、1 を b として選択) tmp;

エラーが存在する可能性があるが、見つけるのが容易ではない別のケースに注意してください。

選択
    (
        場合
        NULLの場合はb
        それ以外         
        終わり
    ) 新品同様、
    、
    b
から
    (NULL を a として、1 を b として選択) tmp;

問題ないように見えますが、実は問題があります。問題の原因は、= を使って null を判定できないことです。簡単に言うと、構文 1 の case 式の値は = を使用した場合に後続の値と比較されますが、MySQL では is または is not を使用する必要があります。

要約:

1: 構文 1 は、case の後の式の値を計算し、次に「=」を使用して when 条件の値が等しいかどうかを判断します。等しい場合は、分岐に入ります。

2: 構文 2 では、case の後に式は必要ありません。when の後に条件値を直接評価できます。true の場合は、入力します。

これで、MySQL で NULL 値を判断する場合に関するこの記事は終了です。MySQL で NULL 値を判断する場合に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL CASE WHEN ステートメントの使用手順
  • MySQLのCASE WHEN文の使用例をいくつか紹介します。
  • MySQL で case when 文を使用して複数条件クエリを実装する方法
  • MySQLソートにおけるCASE WHENの使用例

<<:  よく使われるn番目の子セレクターをまとめる

>>:  Vue プロジェクトにおけるトランジション コンポーネントの適用の概要

推薦する

フレックスレイアウトにおけるflex-growとflex-shrinkの計算方法の詳しい説明

CSS のFlex(彈性布局)すると、Web ページのレイアウトを柔軟に制御できます。Flex Fl...

MySql 8.0 と対応するドライバー パッケージの一致に関する注意事項

MySql 8.0 対応ドライバパッケージのマッチングMySql データベースをバージョン 8.0 ...

ノードイベントループとメッセージキューの分析

目次非同期とは何ですか?なぜ非同期性が必要なのでしょうか?非同期IOとは何ですか?イベントループとは...

vue $setは配列コレクションオブジェクトへの値の割り当てを実装します

Vue $set 配列コレクションオブジェクトの割り当てVue カスタム配列オブジェクト コレクショ...

Jenkins + Docker + ASP.NET Core の自動デプロイメントの問題について (落とし穴を避ける)

このブログを書くつもりはなかったのですが、実際の操作中に、ネットワークの問題に圧倒されたこと (ネッ...

MySQL データ型 DECIMAL の詳細な分析

序文:金額の保存など、小数点数を保存し、精度要件がある場合、通常は DECIMAL フィールド タイ...

MySQL データベースは何をしますか?

MySQL はリレーショナル データベース管理システムです。リレーショナル データベースは、すべて...

MySQLからElasticsearchにデータを同期する方法の詳細な説明

目次1. 同期の原理2. ログスタッシュ入力JDBC 3. go-mysql-elasticsear...

Docker+Jenkinsを使用して自動的にビルドおよびデプロイする

この記事では、Docker+Jenkins の自動ビルドデプロイメントを紹介し、皆さんと共有します。...

MySQL実行計画を学ぶ

目次1. 実施計画の概要2. 実行計画の実践id:選択タイプ:テーブル:タイプ:可能なキー:鍵:キー...

CentOS 7.4 64 ビット版に MySQL 8.0 をインストールして設定するための詳細な手順

ステップ1: MySQL YUMソースを取得するMySQLの公式サイトにアクセスして、RPMパッケー...

etcd クラスターをデプロイするための docker-compose の実装手順

目次docker-compose.ymlを書くdocker-composeを実行するビルドステータス...

Windows 64 ビットに MySQL を再インストールするチュートリアル (Zip バージョン、解凍バージョンの MySQL インストール)

MySQLをアンインストールする1. コントロールパネルで、MySQLのすべてのコンポーネントをア...

Dockerコンテナが停止できない問題の解決方法

解決策は次のとおりです。 1. コンテナを強制削除する docker rm -f ジェンキンス2. ...

ウェブページのメモリ使用量とCPU使用量を削減する方法

一部の Web ページは大きく見えなくても開くのに非常に時間がかかる場合があります。一方、他の We...