0

MySQL で SELECT ステートメントからテンポラル テーブルを作成したいと考えています。これにはいくつかの JOIN が含まれており、MySQL にゼロとして認識させたい NULL 値が生成される可能性があります。簡単な問題のように思えますが (単純にデフォルトをゼロにする)、MySQL (5.6.12) はデフォルト値を引き出すことができません。

たとえば、次の 2 つのテーブルを考えてみましょう。

mysql> select * from TEST1;
+------+------+
| a    | b    |
+------+------+
|    1 |    2 |
|    4 |   25 |
+------+------+
2 rows in set (0.00 sec)

mysql> select * from TEST2;
+------+------+
| b    | c    |
+------+------+
|    2 |  100 |
|    3 |  100 |
+------+------+
2 rows in set (0.00 sec)

左結合は次のようになります。

mysql> select TEST1.*,c from TEST1 left join TEST2 on TEST1.b=TEST2.b;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    1 |    2 |  100 |
|    4 |   25 | NULL |
+------+------+------+
2 rows in set (0.00 sec)

ここで、これらの値をテンポラル テーブルに保存する (NULL をゼロに変更する) 場合は、次のコードを使用します。

mysql> create temporary table TEST_JOIN (a int, b int, c int default 0 not null)
       select TEST1.*,c from TEST1 left join TEST2 on TEST1.b=TEST2.b;
ERROR 1048 (23000): Column 'c' cannot be null

私は何を間違っていますか?最悪の部分は、システム全体のアップグレードを行う前にこのコードが機能していたことです (どのバージョンの MySQL を使用していたかは覚えていませんが、現在の 5.6 よりも低いバージョンだったことは確かです)。以前は、期待どおりの動作を生成していました。NULL の場合は、現在発生しているイライラするエラーではなく、デフォルトを使用してください。

5.6のドキュメントから(4.1 以降変更なし):

NOT NULL と宣言された列に NULL を挿入する。複数行の INSERT ステートメントまたは INSERT INTO ... SELECT ステートメントの場合、列は列データ型の暗黙的なデフォルト値に設定されます。これは、数値型の場合は 0、文字列型の場合は空の文字列 ('')、日付と時刻の型の場合は「ゼロ」値です。INSERT INTO ... SELECT ステートメントは、複数行の挿入と同じように処理されます。これは、サーバーが SELECT からの結果セットを調べて、単一の行が返されるかどうかを確認しないためです。(単一行 INSERT の場合、NULL が NOT NULL 列に挿入されても警告は発生しません。代わりに、ステートメントはエラーで失敗します。)

私の現在の回避策は、NULL値を一時テーブルに格納してからゼロに置き換えることですが、多くの列があるとかなり面倒に思えます (そして非常に非効率的です)。それを行うより良い方法はありますか?

ところで、それは複数行のクエリであるため、クエリ内のいくつかの列を単純に無視することはできません(別の質問で提案されているように)。

4

1 に答える 1

1
IFNULL(`my_column`,0);

これにより、NULL が 0 に設定されます。その他の値はそのまま残ります。

値/列名を IFNULL でラップするだけで、関数に入力したデフォルト値に変換されます。例: 0. または「ヨーロッパのツバメ」など、何でも構いません。

その後、厳密モードをオンのままにして、引き続き NULL を適切に処理できます。

于 2013-08-14T20:59:44.400 に答える