con*_*cat 3 mysql select insert sql-update
在 SELECT 子句具有列别名的查询中尝试将 INSERT、SELECT 和 ON DUPLICATE KEY 链接在一起时,我遇到了一个相当令人惊讶的障碍。例如,请考虑以下情况:
表:
CREATE TABLE source (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
v INT NOT NULL
);
INSERT INTO source (v) VALUES (1), (2), (3);
CREATE TABLE dest (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
v INT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
假设我正在尝试填充dest.v值,POW(source.v,2)而不管值是否dest已经存在。当然,我试过:
INSERT INTO dest
SELECT id, POW(v, 2) AS p FROM source
ON DUPLICATE KEY UPDATE dest.v=source.p;
Run Code Online (Sandbox Code Playgroud)
但是,MySQL 坚持认为 source.p 不存在:
错误 1054 (42S22):“字段列表”中的未知列“source.p”
相当不方便的是,我不得不求助于使用更慢和更麻烦的查询:
INSERT INTO dest
SELECT * FROM (
SELECT id, POW(v, 2) AS p FROM source
) s
ON DUPLICATE KEY UPDATE dest.v=s.p;
Run Code Online (Sandbox Code Playgroud)
这与原始查询几乎没有区别,但有效。为什么会这样?
我总是在下面写查询
INSERT INTO dest ( id, v)
SELECT id, POW(v, 2) AS p FROM source
ON DUPLICATE KEY UPDATE dest.v=VALUES(v);
Run Code Online (Sandbox Code Playgroud)
VALUES() 避免再次编写相同的表达式。始终尝试指定您要插入的列名,以防万一您在将来的某个时间添加新列