2008-09-25 17 views
8

2 tablas:granel actualizar una tabla de filas de otra tabla

Employees 
- EmployeeID 
- LeadCount 


Leads 
- leadID 
- employeeID 

Quiero actualizar la columna Employees.LeadCount contando el # de clientes potenciales en la tabla Leads que tienen el mismo EmployeeID.

Nota: Puede haber más de 1 cliente potencial con el mismo ID de empleado, así que tengo que hacer un DISTINCT(SUM(employeeID)).

Respuesta

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

suma (employeeid) no tiene ningún sentido, y distinto alrededor de un solo valor siempre devolverá el mismo valor, por lo que es redundante. –

+0

IIRC que será realmente lento (MySQL es todo lo que he usado) – BCS

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

Steeling desde arriba y la eliminación de la subconsulta dependiente.

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

EDITAR Es "Agrupar por" no "distinta": b (gracias Marcos Brackett)

3

se une a funcionar de la misma para las actualizaciones (y elimina) igual que lo hacen para selecciona (edit: en algunos RDBMS populares', al menos *):

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 

El SUM (DISTINCT EmployeeId) no tiene sentido - sólo tiene un COUNT (*).

  • MS SQL Server es compatible con UPDATE...FROM y DELETE...FROM sintaxis, al igual que MySql, pero el estándar SQL-92 no lo hace. SQL-92 haría que utilizaras una expresión de fila. Sé que DB2 admite esta sintaxis, pero no está seguro de ninguna otra. Francamente, creo que la versión SQL-92 es confusa, pero los expertos en teoría y teoría argumentarán que la sintaxis FROM viola la teoría relacional y puede llevar a resultados impredecibles con cláusulas JOIN imprecisas o al cambiar de proveedor de RDBMS.
+0

¿Tiene un enlace? Me gustaría aprender más. – BCS

+0

por alguna razón la consulta de actualización es más complicada, ¡con suerte ahora puedo pensar en ellos de la misma manera! –

+0

Las incorporaciones en ACTUALIZAR y ELIMINAR no son SQL estándar, pero algunas implementaciones las admiten como una extensión. ¿Qué marca de RDBMS admite la sintaxis anterior? –

8

Se está configurando para un problema de sincronización de datos. Como las filas en la tabla Leads se insertan, actualizan o eliminan, debe actualizar constantemente la columna Employees.LeadCount.

La mejor solución sería no almacenar la columna LeadCount en absoluto, sino volver a calcular el recuento de clientes potenciales con una consulta agregada de SQL cuando necesite el valor. De esa manera siempre será correcto.

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

La otra solución es la creación de disparadores en la tabla de clientes potenciales para INSERT, UPDATE y DELETE, de manera que se mantiene la columna de la Employees.LeadCount corriente todo el tiempo. Por ejemplo, el uso de sintaxis gatillo MySQL:

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 

Otra opción, si está utilizando MySQL, es utilizar la sintaxis ACTUALIZACIÓN multi-mesa. Esta es una extensión de MySQL para SQL, no es portátil para otras marcas de RDBMS. Primero, restablezca el LeadCount en todas las filas a cero, luego realice un join en la tabla Leads e incremente el LeadCount en cada fila producida por la unión.

UPDATE Employees SET LeadCount = 0; 
UPDATE Employees AS e JOIN Leads AS l USING (employeeID) 
    SET e.LeadCount = e.LeadCount+1; 
+0

si el valor exacto no es necesario, entonces lo que se solicitó podría funcionar muy bien si se ejecuta como una tarea programada de alguna manera. – BCS

+0

+ 1 para no almacenar el LeadCount, pero -1 para el disparador. Creo que deberían ser respuestas separadas realmente. –

Cuestiones relacionadas