2016-10-09 4 views
0

У меня есть следующий 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 | 
+----+-----+-------+------+ 

Я не понимаю, почему? Может кто-то мне помочь, пожалуйста ?

ответ

1

Вы можете использовать order by и limit в формате update в MySQL. Так что, я думаю, что вы имеете в виду:

UPDATE scores 
    SET nom = 'foo', score = 1, rang = 0 
    ORDER BY score DESC 
    LIMIT 1; 
+0

Это правда! Спасибо :) – Erlaunis

1
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 равно ее 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) 

Это говорит, найти самый высокий в scores таблице id, а затем обновить любую строку которого id равно, что конкретной id. Он должен соответствовать только одной строке.

Вы также можете упростить все дело, как Гордон отметил:

UPDATE scores 
SET nom = 'foo', score = 1, rang = 0 
ORDER BY score DESC 
LIMIT 1; 
+0

Интересно, что это получило upvote, потому что большинство запросов будут генерировать ошибки в MySQL. –

+1

отвечает на 'каждая строка таблицы принимает эти значения. Я не понимаю, почему? 'Часть вопроса. Предпоследний запрос дал бы: «Вы не можете указать целевую таблицу для обновления в FROM clause', хотя я себе представляю. –

Смежные вопросы