我有以下SQL:
DROP TABLE IF EXISTS scores;
CREATE TABLE scores
(
id INTEGER PRIMARY KEY,
nom VARCHAR(10),
score INTEGER,
rang INTEGER
);
INSERT INTO scores
VALUES (1,'a',91,11),
(2,'b',92,12),
(3,'c',93,13),
(4,'d',94,14);
UPDATE scores
SET nom = 'foo',
score = 1,
rang = 0
WHERE id = (SELECT id
ORDER BY score DESC
LIMIT 1);
我想只更新得分最高的行(即94)但是当我执行请求时,表的每一行都采用这些值(demo)。
+----+-----+-------+------+
| id | nom | score | rang |
+----+-----+-------+------+
| 1 | foo | 1 | 0 |
| 2 | foo | 1 | 0 |
| 3 | foo | 1 | 0 |
| 4 | foo | 1 | 0 |
+----+-----+-------+------+
我不明白为什么?有人能帮帮我吗?
答案 0 :(得分:1)
您可以在MySQL的order by
中使用limit
和update
。所以,我认为你的意思是:
UPDATE scores
SET nom = 'foo', score = 1, rang = 0
ORDER BY score DESC
LIMIT 1;
答案 1 :(得分:1)
update scores SET nom='foo', score=1, rang=0 WHERE id= (SELECT id order by score DESC LIMIT 1)
想想这句话的内容。请记住,相等性检查限制了行集。每个更新语句都隐含地表示“更新与where子句匹配的每一行”。
首先看一下子查询。
(SELECT id order by score DESC LIMIT 1)
请注意该查询中没有FROM
子句?如果没有FROM
子句,相对于id
和score
列名称是什么?它们与外部陈述有关。 order by score DESC LIMIT 1
具有误导性。他们工作,但他们没有做太多,因为你正在排序一个数字。
对每一行运行此WHERE
子句:
WHERE id= (SELECT id order by score DESC LIMIT 1)
你在说什么,如果他的id
列等于他的id
列,则该行匹配。好吧,对于给定的行,给定列中的值总是等于它自己。
因此,您的整体更新谓词是匹配id
等于其id
的任何行,这自然会匹配每一行。
我认为你的意思是:
update scores
SET nom='foo', score=1, rang=0
WHERE id= (SELECT s.id from scores s order by s.score DESC LIMIT 1)
也就是说,在id
表中找到最高scores
,然后更新id
等于特定id
的任何行。它应该只匹配一行。
戈登指出,你也可以简化整个事情:
UPDATE scores
SET nom = 'foo', score = 1, rang = 0
ORDER BY score DESC
LIMIT 1;