简体   繁体   English

从另一个表的行批量更新表

[英]Bulk updating a table from rows from another table

2 tables: 2桌:

Employees
- EmployeeID
- LeadCount


Leads
- leadID
- employeeID

I want to update the Employees.LeadCount column by counting the # of leads in the Leads table that have the same EmployeeID . 我想通过计算Leads表中具有相同EmployeeID的潜在客户数来更新Employees.LeadCount列。

Note: There may be more than 1 lead with the same employeeID, so I have to do a DISTINCT(SUM(employeeID)) . 注意:可能有多个具有相同employeeID的潜在客户,因此我必须执行DISTINCT(SUM(employeeID))

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

You're setting yourself up for a data synchronization problem. 您正在为数据同步问题做好准备。 As rows in the Leads table are inserted, updated, or deleted, you need to update the Employees.LeadCount column constantly. 在插入,更新或删除Leads表中的行时,您需要不断更新Employees.LeadCount列。

The best solution would be not to store the LeadCount column at all, but recalculate the count of leads with a SQL aggregate query as you need the value. 最好的解决方案是根本不存储LeadCount列,而是在需要值时使用SQL聚合查询重新计算潜在客户数。 That way it'll always be correct. 这样它总是正确的。

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

The other solution is to create triggers on the Leads table for INSERT, UPDATE, and DELETE, so that you keep the Employees.LeadCount column current all the time. 另一种解决方案是在Leads表上为INSERT,UPDATE和DELETE创建触发器,以便始终使Employees.LeadCount列保持最新。 For example, using MySQL trigger syntax: 例如,使用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

Another option, if you are using MySQL, is to use multi-table UPDATE syntax. 如果您使用MySQL,另一个选择是使用多表UPDATE语法。 This is a MySQL extension to SQL, it's not portable to other brands of RDBMS. 这是SQL的MySQL扩展,它不能移植到其他品牌的RDBMS。 First, reset the LeadCount in all rows to zero, then do a join to the Leads table and increment the LeadCount in each row produced by the join. 首先,将所有行中的LeadCount重置为零,然后对Leads表进行连接,并在连接生成的每一行中增加LeadCount。

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

Joins work the same for updates (and deletes) just like they do for selects (edit: in some popular RDBMS', at least*): 连接的工作方式与更新(和删除)相同,就像它们对选择一样(编辑:在一些流行的RDBMS中,至少*):

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  

The SUM(DISTINCT EmployeeId) makes no sense - you just need a COUNT(*). SUM(DISTINCT EmployeeId)毫无意义 - 你只需要一个COUNT(*)。

  • MS SQL Server supports UPDATE...FROM , and DELETE...FROM syntax, as does MySql , but the SQL-92 standard does not. MS SQL Server支持UPDATE ... FROMDELETE ... FROM语法, MySql也支持 ,但SQL-92标准不支持。 SQL-92 would have you use a row expression. SQL-92会让你使用行表达式。 I know that DB2 supports this syntax, but not sure of any others. 我知道DB2支持这种语法,但不确定其他任何语法。 Frankly, I find the SQL-92 version confusing - but standards and theory wonks will argue that the FROM syntax violates relational theory and can lead to unpredictable results with imprecise JOIN clauses or when switching RDBMS vendors. 坦率地说,我发现SQL-92版本令人困惑 - 但标准和理论方面的人会争辩说,FROM语法违反了关系理论,并且可能导致不可预测的结果,不精确的JOIN子句或切换RDBMS供应商时。
UPDATE Employees SET LeadCount = (
  SELECT Distinct(SUM(employeeID)) FROM Leads WHERE Leads.employeeId = Employees.employeeId
)

Steeling from above and removing the dependent subquery. 从上面进行钢化并删除从属子查询。

// 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 It's "group By" not "distinct" :b (thanks Mark Brackett) 编辑它是“group By”而不是“distinct”:b(感谢Mark Brackett)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM