INSERT + SELECT + ON DUPLICATE KEY 在 SELECT 子句中使用列别名

问题描述 投票:0回答:2

当我尝试在 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
);

假设我尝试用

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;

但是,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;

与原始查询差别很小,但有效。为什么会这样?

mysql select insert sql-update
2个回答
8
投票

我总是按如下方式编写查询

INSERT INTO dest ( id, v)
SELECT id, POW(v, 2) AS p FROM source 
ON DUPLICATE KEY UPDATE dest.v=VALUES(v);

VALUES() 避免再次编写相同的表达式。始终尝试指定要插入的列名称,以防万一您将来某个时候向表中添加新列


0
投票

函数的别名只是由mysql评估后直接使用。另一种不太糟糕的查询可能是:

INSERT INTO dest (v) 
    SELECT POW(v, 2) AS p FROM source 
    ON DUPLICATE KEY UPDATE dest.v=POW(v, 2);

(未经测试...)

© www.soinside.com 2019 - 2024. All rights reserved.