проблема с обновлением в MySQL - PullRequest
1 голос
/ 27 апреля 2009

Согласно документации, объединения при использовании с оператором обновления работают так же, как при использовании в выборках.

Например, если у нас есть эти две таблицы:

mysql> SELECT * FROM orders;
+---------+------------+
| orderid | customerid |
+---------+------------+
|       1 |          1 |
|       2 |          2 |
|       3 |          3 |
|       4 |          1 |
+---------+------------+

mysql> SELECT * FROM customers;
+------------+------------+
| customerid | ordercount |
+------------+------------+
|          1 |          9 |
|          2 |          3 |
|          3 |          8 |
|          4 |          5 |
|          5 |          7 |
+------------+------------+

с помощью этого оператора select:

SELECT orders.customerid 
FROM orders 
JOIN customers ON (customers.customerid = orders.customerid)

возвращается:

+------------+
| customerid |
+------------+
|          1 |
|          1 |
|          2 |
|          3 |
+------------+

Итак, я ожидал следующего утверждения:

UPDATE orders 
JOIN customers ON (customers.customerid = orders.customerid) 
SET ordercount = ordercount + 1

чтобы обновить количество заказов для клиента # 1 (customerid = 1), равное 11, но на самом деле это не так. Вот результаты после обновления:

mysql> SELECT * FROM customers;
+------------+------------+
| customerid | ordercount |
+------------+------------+
|          1 |         10 |
|          2 |          4 |
|          3 |          9 |
|          4 |          5 |
|          5 |          7 |
+------------+------------+

Как видите, он был увеличен только один раз, несмотря на то, что он встречается дважды в таблице заказов, и, несмотря на это, оператор select возвращает его правильно.

Это ошибка в MySQL или я что-то не так делаю? Я стараюсь избегать использования группы по причинам производительности, поэтому мне интересно понять, что происходит.

Заранее спасибо

1 Ответ

2 голосов
/ 27 апреля 2009

Да, MySQL обновляет каждую запись в объединенной таблице не более одного раза.

Я не могу найти это в документации, но практика так говорит.

Я, вероятно, опубликую это как ошибку, поэтому они, по крайней мере, добавят ее в документацию:

CREATE TABLE updater (value INT NOT NULL);

INSERT
INTO    updater
VALUES  (1);

SELECT  *
FROM    updater;

value
---
1

UPDATE  updater u
JOIN    (
        SELECT  1 AS newval
        UNION ALL
        SELECT  2
        ) q
SET     u.value = u.value + newval;

SELECT  *
FROM    updater;

value
---
2

(expected 4).

SQL Server, кстати, ведет себя одинаково в нескольких таблицах UPDATE.

Вы можете использовать:

UPDATE  orders o
SET     ordercount = ordercount +
        (
        SELECT  COUNT(*)
        FROM    customers c
        WHERE   c.customerid = o.customerid
        )

, что соответствует производительности, если у вас есть индекс customers (customer_id)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...