0

我想从 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值存储在临时表中,然后用零替换它们,但是对于许多列来说似乎相当麻烦(而且效率极低)。有更好的方法吗?

顺便说一句,我不能简单地忽略查询中的某些列(如另一个问题所建议的那样),因为它是一个多行查询。

4

1 回答 1

1
IFNULL(`my_column`,0);

这会将 NULL 设置为 0。其他值保持不变。

只需用 IFNULL 包装您的值/列名称,它就会将它们转换为您放入函数的任何默认值。例如 0。或者“欧洲燕子”,或者任何你想要的。

然后,您可以保持严格模式打开并仍然优雅地处理 NULL。

于 2013-08-14T20:59:44.400 回答