【问题标题】:How to insert the default value in temporal tables in MySQL?如何在 MySQL 的时态表中插入默认值?
【发布时间】:2013-08-17 00:26:24
【问题描述】:

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

顺便说一句,我不能简单地忽略查询中的某些列 (as suggested for another question),因为它是一个多行查询。

【问题讨论】:

标签: mysql


【解决方案1】:
IFNULL(`my_column`,0);

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

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

然后你可以保持 严格模式 并且仍然优雅地处理 NULL。

【讨论】:

  • IFNULL() 接受 两个 参数。这里很可能是列名,然后是默认值。
  • 哎呀,谢谢。我在我的答案中修复了它。我刚刚注意到您进行了编辑,但我认为我的相似。再次感谢您指出这一点。
  • 这解决了它:创建临时表 TEST_JOIN (a int, b int, c int default 0 not null) select TEST1.*,IFNULL(c,0) as c from TEST1 left join TEST2 on TEST1 .b=TEST2.b;
猜你喜欢
  • 2012-02-05
  • 2015-05-24
  • 2019-05-02
  • 2011-07-20
  • 2018-05-18
  • 2016-06-01
  • 2016-01-31
  • 2023-03-29
  • 1970-01-01
相关资源
最近更新 更多