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
値を一時テーブルに格納してからゼロに置き換えることですが、多くの列があるとかなり面倒に思えます (そして非常に非効率的です)。それを行うより良い方法はありますか?
ところで、それは複数行のクエリであるため、クエリ内のいくつかの列を単純に無視することはできません(別の質問で提案されているように)。