#mysql #sql
#mysql #sql
Вопрос:
У меня есть следующий 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), но когда я выполняю запрос, каждая строка таблицы принимает эти значения (демонстрация).
---- ----- ------- ------
| id | nom | score | rang |
---- ----- ------- ------
| 1 | foo | 1 | 0 |
| 2 | foo | 1 | 0 |
| 3 | foo | 1 | 0 |
| 4 | foo | 1 | 0 |
---- ----- ------- ------
Я не понимаю, почему? Может кто-нибудь мне помочь, пожалуйста?
Ответ №1:
Вы можете использовать order by
и limit
update
в MySQL. Итак, я думаю, вы имеете в виду:
UPDATE scores
SET nom = 'foo', score = 1, rang = 0
ORDER BY score DESC
LIMIT 1;
Комментарии:
1. Это правда ! Спасибо 🙂
Ответ №2:
update scores SET nom='foo', score=1, rang=0 WHERE id= (SELECT id order by score DESC LIMIT 1)
Подумайте о том, что говорит это утверждение. Помните, что проверки на равенство — это то, что ограничивает набор строк. Каждый оператор update неявно означает «обновлять каждую строку, соответствующую предложению 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
равна its 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;
Комментарии:
1. Интересно, что это получило одобрение, потому что большинство запросов будут генерировать ошибки в MySQL.
2. это отвечает на
every line of the table are taking these values. I don't understand why?
часть вопроса. Предпоследний запрос выдалYou can't specify target table for update in FROM clause
бы ошибку, хотя я полагаю.