2009-04-27 12 views
1

Laut der Dokumentation arbeiten Joins, wenn mit der Update-Anweisung verwendet, auf die gleiche Weise wie in Selects verwendet.Problem mit Update in MySQL

Zum Beispiel, wenn wir diese beiden Tabellen:

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 | 
+------------+------------+ 

diese select-Anweisungen mit:

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

kehrt:

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

Also, ich hatte erwartet, die Erklärung unten :

zu aktualisieren Ordercount für Kunden # 1 (customerid = 1) 11 sein, aber eigentlich ist dies nicht der Fall, hier sind die Ergebnisse nach dem Update:

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

Wie Sie es nur war sehen inkrementiert einmal, obwohl es zweimal in der Befehlstabelle vorkommt und trotzdem gibt die select-Anweisung es korrekt zurück.

Ist das ein Fehler in MySQL oder mache ich etwas falsch? Ich versuche zu vermeiden, Gruppen aus Performancegründen zu verwenden, daher mein Interesse zu verstehen, was vor sich geht.

Vielen Dank im Voraus

+0

konnte, dass dieses Problem indirekt einen Fehler in Ihrem db Design zeigt? vielleicht ist es zu viel Mühe, eine Bestellung zu halten. Es kann zu Inkonsistenzen kommen, wenn Sie solche Bewertungen durch unabhängige Aktualisierungen anpassen. Vielleicht wäre es besser, diese Anzahl mit einer Abfrage zu generieren, wenn Sie sie brauchen. – markus

+0

Ich habe nur die Kunden und Bestellungen Beispiel verwendet, um das Problem zu demonstrieren, ich werde es nicht auf diese Weise verwenden –

Antwort

2

Ja, MySQL aktualisiert jeden Datensatz in einer verknüpften Tabelle am meisten auf einmal.

Ich kann es in der Dokumentation nicht finden, aber Praxis sagt so.

ich es wahrscheinlich als Fehler veröffentlichen werde, so dass sie es zumindest Dokumentation hinzuzufügen:

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, nebenbei bemerkt, verhält sich UPDATE in einem Mehr Tabelle gleich.

können Sie verwenden:

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

, die so lange auf die Leistung gleich ist, wie Sie sein, einen Index haben es auf customers (customer_id)

+0

Also, ist das von Entwurf? Die Dokumentation sagt nichts über diese –

+0

Entschuldigung dafür, dies nicht in der Frage zu erwähnen, aber tatsächlich habe ich mehr Kriterien in der Join-Anweisung, die ich aus Gründen der Dinge einfacher entfernt .. dieser Code in Ihrer Antwort wird die gesamte Tabelle aktualisieren was ist nicht das, was ich will, Kunden können eine große Anzahl von Datensätzen haben (es ist keine Kunden-Tabelle übrigens, die nur zur Demonstration des Problems verwendet wurde), die Join-Ergebnisse nur ein paar Datensätze aktualisiert werden –

+0

Danke für Ihre detaillierte antwort .. tatsächlich verwende ich nur ein paar aufzeichnungen in aufträge (mit einigen kriterien), um die kunden-tabelle zu aktualisieren .. scheint wie mit GROUP BY ist der einzige weg –