我想从 MySQL 中的 SELECT 语句创建一个临时表。它涉及多个 JOIN,它可以产生我希望 MySQL 将其设为零的 NULL 值。这听起来像是一个简单的问题(只是默认为零),但 MySQL (5.6.12) 无法得出默认值。
比如下面两张表:
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 起未更改):
将 NULL 插入已声明为 NOT NULL 的列中。对于多行 INSERT 语句或 INSERT INTO ... SELECT 语句,列设置为列数据类型的隐式默认值。数字类型为 0,字符串类型为空字符串 (''),日期和时间类型为“零”值。INSERT INTO ... SELECT 语句的处理方式与多行插入相同,因为服务器不会检查来自 SELECT 的结果集以查看它是否返回单行。(对于单行 INSERT,将 NULL 插入 NOT NULL 列时不会出现警告。相反,该语句会因错误而失败。)
我目前的解决方法是将NULL
值存储在临时表中,然后用零替换它们,但是对于许多列来说似乎相当麻烦(而且效率极低)。有更好的方法吗?
顺便说一句,我不能简单地忽略查询中的某些列(如另一个问题所建议的那样),因为它是一个多行查询。