MySQL 文档说明了这一点:
在 UPDATE 子句中使用 VALUES() 的 INSERT ... SELECT ... ON DUPLICATE KEY UPDATE 语句(如下所示)会引发警告:
INSERT INTO t1 SELECT c, c+d FROM t2 ON DUPLICATE KEY UPDATE b = VALUES(b);
您可以通过使用子查询来消除此类警告,如下所示:
INSERT INTO t1 SELECT * FROM (SELECT c, c+d AS e FROM t2) AS dt ON DUPLICATE KEY UPDATE b = e;
我想知道为什么我们不能将
c+d
别名为 e
并这样引用它?例如,
INSERT INTO t1
SELECT c, c+d as e FROM t2
ON DUPLICATE KEY UPDATE b = e;
如果根本不使用,为什么还需要
dt
?
我看不出简单地删除外部 select 语句会产生什么歧义。
你也可以重复这个表达,但我知道有人不想这样做。
INSERT INTO t1
SELECT c, c+d as e FROM t2
ON DUPLICATE KEY UPDATE b = c+d;
文档没有说得那么清楚,但我认为 select-list 中定义的别名不能在
UPDATE
子句中使用的原因与不能在 中使用别名的原因类似WHERE
定义该别名的查询子句。
SELECT x, x+y AS z
FROM ...
WHERE z = 100; -- column 'z' is unknown at this level
但是您可以引用子查询中定义的别名:
SELECT x, z
FROM (
SELECT x, x+y AS z
FROM ...
) AS sub
WHERE z = 100; -- OK
关于不在定义别名的查询的
WHERE
子句中使用别名(即不在子查询中)的规则记录在此处:https://dev.mysql.com/doc/refman/en/problems- with-alias.html
标准 SQL 不允许在 WHERE 子句中引用列别名。施加此限制是因为当计算 WHERE 子句时,列值可能尚未确定。