2009-04-27 65 views
1

根据文档,与update语句一起使用时,连接的工作方式与在select中使用的方式相同。MySQL中的更新问题

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

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(客户ID = 1)为11,但实际上这是不是这样的,这里是更新后的结果:

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

正如你可以看到它是唯一尽管它在订单表中出现了两次,尽管select语句正确地返回了它,但仍会增加一次。

这是MySQL中的错误还是我做错了什么?我试图避免使用group by来获得性能方面的原因,因此我很有兴趣了解发生了什么。

在此先感谢

+0

索引对性能同样会不会是这个问题间接地显示在你的数据库设计缺陷?也许这对保持订单计数来说太麻烦了。如果您通过独立更新调整此类分数,它可能会导致不一致。也许最好是在需要的时候用查询生成计数。 – markus 2009-04-27 12:09:21

+0

我只使用客户和订单示例来演示问题,我不打算以这种方式使用它 – 2009-04-27 12:19:19

回答

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)