2008-09-25 21 views
8

2 Tabellen Aktualisierung:Masse eine Tabelle aus Zeilen aus einer anderen Tabelle

Employees 
- EmployeeID 
- LeadCount 


Leads 
- leadID 
- employeeID 

möchte ich durch Zählen der Anzahl der Leitungen in der Leads Tabelle die Employees.LeadCount Spalte aktualisieren, die denselben EmployeeID haben.

Hinweis: Es kann mehr als 1 Blei mit der gleichen Mitarbeiter-ID geben, also muss ich eine DISTINCT(SUM(employeeID)) tun.

Antwort

1
UPDATE Employees SET LeadCount = (
    SELECT Distinct(SUM(employeeID)) FROM Leads WHERE Leads.employeeId = Employees.employeeId 
) 
+0

sum (employeeID) macht keinen Sinn, und distinct um einen einzelnen Wert wird immer den gleichen Wert zurückgeben, so dass es redundant ist. –

+0

IIRC, das wird wirklich langsam (MySQL ist alles, was ich verwendet habe) – BCS

12
UPDATE 
    Employees E 
SET 
    E.LeadCount = (
     SELECT COUNT(L.EmployeeID) 
     FROM Leads L 
     WHERE L.EmployeeID = E.EmployeeID 
    ) 
0

von oben Steeling und der abhängigen Unterabfrage zu entfernen.

// create tmp -> TBL (EmpID, count) 

insert into TBL 
    SELECT employeeID COUNT(employeeID) Di 
    FROM Leads WHERE Leads.employeeId = Employees.employeeId GROUP BY EmployeeId 
UPDATE Employees SET LeadCount = (
    SELECT count FROM TBL WHERE TBL.EmpID = Employees.employeeId 
) 

// drop TBL 

EDIT Es ist "Gruppe von" nicht "distinct": b (durch Mark Brackett)

3

tritt der gleiche gilt für Updates arbeiten (und löscht) wie sie für wählt tun (edit: in einige beliebte RDBMS‘, zumindest *):

UPDATE Employees SET 
    LeadCount = Leads.LeadCount 
FROM Employee 
JOIN (
    SELECT EmployeeId, COUNT(*) as LeadCount 
    FROM Leads 
    GROUP BY EmployeeId 
) as Leads ON 
    Employee.EmployeeId = Leads.EmployeeId 

Die SUM (DISTINCT EmployeeId) macht keinen Sinn - Sie brauchen nur einen COUNT (*).

  • MS SQL Server unterstützt UPDATE...FROM und DELETE...FROM Syntax, wie MySql tut, aber der SQL-92-Standard nicht. In SQL-92 würden Sie einen Zeilenausdruck verwenden. Ich weiß, dass DB2 diese Syntax unterstützt, aber anderer nicht sicher ist. Ehrlich gesagt, finde ich die SQL-92-Version verwirrend - aber Standards und Theorie werden argumentieren, dass die FROM-Syntax relationale Theorie verletzt und zu unvorhersehbaren Ergebnissen mit ungenauen JOIN-Klauseln oder beim Wechsel von RDBMS-Anbietern führen kann.
+0

Haben Sie einen Link? Ich würde gerne mehr erfahren. – BCS

+0

aus irgendeinem Grund ist die Update-Abfrage komplizierter, hoffentlich kann ich jetzt auf die gleiche Weise an sie denken! –

+0

Joins in UPDATE und DELETE sind keine Standard-SQL, aber einige Implementierungen unterstützen sie als Erweiterung. Welche RDBMS-Marke unterstützt die obige Syntax? –

8

Sie bereiten sich auf ein Datensynchronisierungsproblem vor. Wenn Zeilen in der Leads-Tabelle eingefügt, aktualisiert oder gelöscht werden, müssen Sie die Spalte Employees.LeadCount ständig aktualisieren.

Die beste Lösung wäre, die LeadCount-Spalte überhaupt nicht zu speichern, sondern die Anzahl der Leads mit einer SQL-Aggregatabfrage neu zu berechnen, wenn Sie den Wert benötigen. So wird es immer stimmen.

SELECT employeeID, COUNT(leadId) AS LeadCount 
FROM Leads 
GROUP BY employeeID; 

Die andere Lösung ist Auslöser auf der Leads Tabelle für INSERT, UPDATE und DELETE, zu erstellen, so dass Sie die Employees.LeadCount Spaltenstrom die ganze Zeit halten. Zum Beispiel mit MySQL Trigger Syntax:

CREATE TRIGGER leadIns AFTER INSERT ON Leads 
FOR EACH ROW BEGIN 
    UPDATE Employees SET LeadCount = LeadCount + 1 WHERE employeeID = NEW.employeeID; 
END 

CREATE TRIGGER leadIns AFTER UPDATE ON Leads 
FOR EACH ROW BEGIN 
    UPDATE Employees SET LeadCount = LeadCount - 1 WHERE employeeID = OLD.employeeID; 
    UPDATE Employees SET LeadCount = LeadCount + 1 WHERE employeeID = NEW.employeeID; 
END 

CREATE TRIGGER leadIns AFTER DELETE ON Leads 
FOR EACH ROW BEGIN 
    UPDATE Employees SET LeadCount = LeadCount - 1 WHERE employeeID = OLD.employeeID; 
END 

Eine weitere Option, wenn Sie MySQL verwenden, ist Multi-Table UPDATE Syntax zu verwenden. Dies ist eine MySQL-Erweiterung für SQL, die nicht auf andere RDBMS-Marken übertragbar ist. Setzen Sie zuerst den LeadCount in allen Zeilen auf Null zurück, führen Sie dann einen Join zur Leads-Tabelle aus und erhöhen Sie den LeadCount in jeder vom Join erzeugten Zeile.

+0

Wenn der genaue Wert nicht benötigt wird, dann könnte das, was angefordert wurde, sehr gut funktionieren, wenn es in irgendeiner Weise als geplante Aufgabe ausgeführt wird. – BCS

+0

+ 1, um den LeadCount nicht zu speichern, aber -1 für den Trigger. Ich denke, dass sie wirklich getrennte Antworten sein sollten. –

Verwandte Themen