обновление, выполняемое для каждой строки таблицы

#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 бы ошибку, хотя я полагаю.