简体   繁体   English

为什么 SQL 查询不更新特定行

[英]Why does SQL query not update specific row

Suppose I have this query:假设我有这个查询:

UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT max(customerid));

Which is meant to change the customer age to 17 for the highest customerid.这意味着将最高客户 ID 的客户年龄更改为 17 岁。 But, all customer's age change to this value, regardless of ID, why is this?但是,无论ID如何,所有客户的年龄都更改为该值,这是为什么?

The result of:的结果:

(SELECT max(customerid))

is not the maximum customerid of the table since you did not include a FROM clause.不是表的最大customerid ,因为您没有包含FROM子句。
What is odd is that the code runs without any errors and as it seems this SELECT returns the customerid of each row!!!奇怪的是代码运行时没有任何错误,而且这个 SELECT 似乎返回每一行的customerid !!!
But even if you included the FROM clause the code would result in the error:但即使你包含了FROM子句,代码也会导致错误:

Error: ER_UPDATE_TABLE_USED: You can't specify target table 'customerDetails ' for update in FROM clause错误:ER_UPDATE_TABLE_USED:您不能在 FROM 子句中为更新指定目标表“customerDetails”

Mysql allows the subquery only if it is nested inside another one like this: Mysql 只允许子查询嵌套在另一个这样的子查询中:

UPDATE customerDetails 
SET age = 17
WHERE customerid = (SELECT t.maxid FROM (SELECT max(customerid) maxid FROM customerDetails) t);

You can do it like this:你可以这样做:

UPDATE customerDetails 
SET age = 17
ORDER BY customerid DESC 
LIMIT 1

What this does is selecting all the data, then order's it by customerid in descending order(that means the first one will be the one with the largest customerid) and then takes the first result with LIMIT 1 and makes an update to that row.这样做是选择所有数据,然后按 customerid 降序排序(这意味着第一个将是具有最大 customerid 的数据),然后使用LIMIT 1获取第一个结果并更新该行。

Here is a small DEMO 这是一个小DEMO

One more way to do it is:另一种方法是:

with cte as(
select max(customerid) as id 
from customerDetails
)
update  customerDetails c
set age = 17 
where c.customerid = (select id from cte);

The query doesn't make sense.查询没有意义。 You are saying WHERE customerid = (SELECT max(customerid)) This would get the max id for each row individually.您说的是WHERE customerid = (SELECT max(customerid))这将分别获得每一行的最大 id。 If you want just the max id from the entire table, you need to check the entire table again.如果您只想要整个表的最大 id,则需要再次检查整个表。 You can do this by doing it this way:你可以这样做:

UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT max(c.customerid) FROM customerDetails c);
UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT max(customerid));

What is happening here?这里发生了什么? The update statement goes through the table row by row and checks whether the row matches the select clause. update 语句逐行遍历表并检查该行是否与 select 子句匹配。 In the subquery there is no from clause, so you are not selecting from some table there.在子查询中没有 from 子句,因此您不是从那里的某个表中进行选择。 Instead you access the customerid of the row you are currently looking at (it is the only customerid that exists in that context).相反,您可以访问当前正在查看的行的customerid (它是该上下文中唯一存在的customerid )。 This is one value (one row, one column) and the maximum of that value is the value itself.这是一个值(一行,一列),该值的最大值是值本身。 So, what you have is:所以,你所拥有的是:

UPDATE customerDetails SET age = 17
WHERE customerid = customerid;

The condition customerid = customerid is true for every row in the table and you update all rows hence.条件customerid = customerid对表中的每一行都成立,因此您更新所有行。

What you want instead is to update the row the customerid of which matches the maximum customerid in the table:你想,而不是什么是更新该行的customerid ,其中最大匹配customerid在该表:

UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT MAX(customerid) FROM customerDetails);

MySQL, however, has problems with accessing the same table that you are updating.但是,MySQL 在访问您正在更新的同一个表时存在问题。 So you will have to select from the table one level deeper, which makes this a tad clumsy:所以你必须从表中选择更深一层,这使得这有点笨拙:

UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT MAX(customerid) FROM (SELECT * FROM customerDetails) q);

The following should work:以下应该工作:

create table temp as select max(customerid) max_id from customerDetails;
UPDATE customerDetails SET age = 17
WHERE customerid = (SELECT max_id from temp);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM