不能在 FROM 子句中指定更新的目标表
我有一个简单的 mysql 表:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
我尝试运行以下更新,但只收到错误 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
我搜索了该错误并从 mysql 以下页面找到 http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html,但事实并非如此别帮我。
我该怎么做才能纠正sql查询?
I have a simple mysql table:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
I tried to run following update, but I get only the error 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
I searched for the error and found from mysql following page http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html, but it doesn't help me.
What shall I do to correct the sql query?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
问题是,无论出于什么愚蠢的原因,MySQL 不允许您编写这样的查询:
也就是说,如果您正在执行
UPDATE
/INSERT
/< code>DELETE 在表上,您不能在内部查询中引用该表(但是您可以引用该外部表中的字段...)解决方案是将子查询中的
myTable
实例替换为(SELECT * FROM myTable)
,就像这样这显然会导致必要的字段被隐式复制到临时表,所以这是允许的。
我找到了这个解决方案
The problem is that MySQL, for whatever inane reason, doesn't allow you to write queries like this:
That is, if you're doing an
UPDATE
/INSERT
/DELETE
on a table, you can't reference that table in an inner query (you can however reference a field from that outer table...)The solution is to replace the instance of
myTable
in the sub-query with(SELECT * FROM myTable)
, like thisThis apparently causes the necessary fields to be implicitly copied into a temporary table, so it's allowed.
I found this solution here. A note from that article:
您可以通过三个步骤完成此操作:
...
或
You can make this in three steps:
...
or
从子查询创建临时表(tempP)
我引入了一个单独的名称(别名),并为临时表的“persID”列指定了新名称
Make a temporary table (tempP) from a subquery
I've introduced a separate name (alias) and give a new name to 'persID' column for temporary table
在Mysql中,你不能通过子查询同一张表来更新一张表。
您可以将查询分成两部分,或者执行
In Mysql, you can not update one table by subquery the same table.
You can separate the query in two parts, or do
这很简单。例如,
您应该写
或类似的内容,而不是写:
It's quite simple. For example, instead of writing:
you should write
or similar.
BlueRaja 发布的方法很慢我将其修改为
我用来从表中删除重复项。如果它对任何拥有大桌子的人有帮助
原始查询
这需要更多时间:
更快的解决方案
The Approach posted by BlueRaja is slow I modified it as
I was using to delete duplicates from the table. In case it helps anyone with large tables
Original Query
This is taking more time:
Faster Solution
MySQL 不允许同时从表中进行选择并在同一个表中进行更新。但总有一个解决方法:)
这不起作用 >>>>
但是这有效 >>>>
MySQL doesn't allow selecting from a table and update in the same table at the same time. But there is always a workaround :)
This doesn't work >>>>
But this works >>>>
作为参考,您还可以使用Mysql变量来保存临时结果,例如:
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
Just as reference, you can also use Mysql Variables to save temporary results, e.g.:
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
MariaDB 从 10.3.x 开始已取消此功能(对于
DELETE
和UPDATE
):DBFiddle MariaDB 10.2 - 错误
DBFiddle MariaDB 10.3 - 成功
MariaDB has lifted this starting from 10.3.x (both for
DELETE
andUPDATE
):DBFiddle MariaDB 10.2 - Error
DBFiddle MariaDB 10.3 - Success
如果您尝试从 tableA 读取 fieldA 并将其保存到同一个表的 fieldB 上,则当 fieldc = fieldd 时,您可能需要考虑这一点。
当条件字段满足您的条件时,上面的代码将值从 fieldA 复制到 fieldB。这也适用于 ADO(例如 access )
源:我自己尝试过
If you are trying to read fieldA from tableA and save it on fieldB on the same table, when fieldc = fieldd you might want consider this.
Above code copies the value from fieldA to fieldB when condition-field met your condition. this also works in ADO (e.g access )
source: tried myself
其他解决方法包括在子查询中使用 SELECT DISTINCT 或 LIMIT,尽管这些对具体化的影响并不明确。这对我有用
如 MySql Doc 中所述
Other workarounds include using SELECT DISTINCT or LIMIT in the subquery, although these are not as explicit in their effect on materialization. this worked for me
as mentioned in MySql Doc
您可以使用此查询
在此处输入图像描述
来
在此处输入图像描述
you can use this query
enter image description here
to
enter image description here