Mysql 在SELECT子句中具有列别名的重复键上插入+SELECT+

Mysql 在SELECT子句中具有列别名的重复键上插入+SELECT+,mysql,select,insert,sql-update,Mysql,Select,Insert,Sql Update,在SELECT子句具有列别名的查询中,当尝试将INSERT、SELECT和ON DUPLICATE键链接在一起时,我遇到了一个相当令人惊讶的障碍。例如,考虑以下情况: 表: 假设我试图用POWsource.v的值填充dest.v,2,不管dest中是否已经存在值。当然,我试过: INSERT INTO dest SELECT id, POW(v, 2) AS p FROM source ON DUPLICATE KEY UPDATE dest.v=source.p; 但是,

在SELECT子句具有列别名的查询中,当尝试将INSERT、SELECT和ON DUPLICATE键链接在一起时,我遇到了一个相当令人惊讶的障碍。例如,考虑以下情况:

表:

假设我试图用POWsource.v的值填充dest.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评估以供直接使用。另一个稍微不那么糟糕的查询可能是:

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

未测试…

我总是将查询写在下面

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

值避免再次写入相同的表达式。始终尝试指定要插入的列名称,以防在将来某个时间向列表中添加新列

因此,如果dest中存在键,则SELECT子句中不计算POWv,2?如果对其进行计算,则仅分配的别名不可用。我们可以称之为MySQL的改进点。在更多的情况下,你会遇到这种情况。也许MariaDB项目会更快地处理这类改进等待和查看您的替代代码只是添加一组新的记录,因为select结果中没有键字段来进行重复的键命中;将dest.v设置为自身。也许我应该澄清一下:如果源代码中的值发生更改,查询需要更改dest中的值。例如,如果我运行更新源集v=v*2;,从dest中选择v,其中id=3在该场景中应产生36。valuesv表示将使用您在插入中制定的值。请阅读手册中的更多内容:哦,真的!对不起,我误解了;我误解了价值观的作用。
INSERT INTO dest ( id, v)
SELECT id, POW(v, 2) AS p FROM source 
ON DUPLICATE KEY UPDATE dest.v=VALUES(v);