MySQL中的更新问题

时间:2009-04-27 11:49:42

标签: sql mysql

根据文档,join与update语句一起使用时的工作方式与select中使用的方式相同。

例如,如果我们有这两个表:

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)的ordercount更新为11,但实际情况并非如此,这是更新后的结果:

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

正如你所看到的那样,它只增加了一次,尽管它在orders表中出现了两次,尽管select语句正确地返回它。

这是MySQL中的错误还是我做错了?我试图避免因为性能原因而使用group by,因此我有兴趣了解正在发生的事情。

提前致谢

1 个答案:

答案 0 :(得分:2)

是的,MySQL最多只更新一次联接表中的每条记录。

我在文档中找不到它,但是练习就这么说了。

我可能会把它发布为一个bug,所以他们至少将它添加到文档中:

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)

上有索引,就性能相同