我想从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,字符串为空字符串('') 类型,以及日期和时间类型的“零”值。插入 ... SELECT语句的处理方式与多行插入的处理方式相同 因为服务器不会检查SELECT中的结果集 看它是否返回一行。 (对于单行INSERT,没有 将NULL插入NOT NULL列时发生警告。代替, 该陈述失败并出现错误。)
我目前的解决方法是将NULL
值存储在时态表中,然后用零替换它们,但是对于许多列而言似乎相当麻烦(而且非常低效)。有没有更好的方法呢?
BTW,我不能简单地忽略查询中的某些列(as suggested for another question),因为它是一个多行查询。
答案 0 :(得分:1)
IFNULL(`my_column`,0);
这会将NULL设置为0.其他值保持不变。
只需用IFNULL包装您的值/列名称,它就会将它们转换为您放入函数的默认值。例如。 0.或“欧洲燕子”,或任何你想要的。
然后你可以保持严格模式,并且仍然可以优雅地处理NULL。