2012-03-04 91 views
1

我有2个表 - 一个主和细节。这是主对象与细节之间的一对多关系。MySQL如何更新来自许多详细记录的1条主记录

以及许多其他列,则master table有:

id column (index) 
total column 

以及许多其他列,则details table有:

id column (index) 
value column 

可能SQL UPDATE语句是什么样子加入这两个表连接在一起和UPDATE master.total with the sum of details.value where master.id = details.id

感谢您的帮助。

回答

2
update master as m 
set total= 
(select sum(value) from detail as d where d.id=m.id) 
+0

你能解释一下这个答案和MGA之间的区别吗? – 2012-03-04 12:59:08

+0

完美的@hago作品。谢谢!由于简单和它在我的第一次传递中起作用的事实表明这是回答。 – 2012-03-04 13:32:37

+0

@ypercube感谢MGA,他的回答可能比我的要快。我可能会多次执行对细节表的查询,并且他只使用一次内部连接查询细节表,特别是当您有大量数据时,我的操作只是简单易懂。 – hago 2012-03-04 15:28:34

3

看起来类似:

UPDATE 
master m 
INNER JOIN 
( 
    SELECT d.id, SUM(d.value) AS valueSum 
    FROM details 
    GROUP BY d.id 
) AS g 
    ON m.id = g.id 
SET m.total = g.valueSum 
+0

谢谢@MGA。现在尝试。 – 2012-03-04 12:46:00

+0

我试过这个,但考虑到整个语法和我复杂的现有INNER JOIN ON语法的复杂性(我知道这是有效的)我得到'你的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以获取在接近'处使用的正确语法。所以我会尝试[在] hago的版本低于 – 2012-03-04 13:23:38

+0

它看起来不错,可能工作。我无法让它为我工作。由于事实上我投了其他答案,我马上就开始工作。感谢分享。 – 2012-03-04 13:33:59

1

这是我最后的SELECT语句结束什么看起来像:

// update all scored nominations "total score" and "average score" for current year where nomination approved and not locked 
mysql_query(' 
    UPDATE nomination_bak AS nomination 
    SET 
     nomination_score = (
      SELECT SUM(total_score) 
      FROM essayScores_bak AS essayScores 
      WHERE essayScores.nomination_sequence = nomination.nomination_sequence AND essayScores.nomination_year = nomination.nomination_year 
     ), 
     nomination_average = (
      SELECT AVG(total_score) 
      FROM essayScores_bak AS essayScores 
      WHERE essayScores.nomination_sequence = nomination.nomination_sequence AND essayScores.nomination_year = nomination.nomination_year AND essayScores.total_score > "0" 
     ) 
    WHERE nomination.nomination_year = "' . NOMINATION_YEAR . '" AND nomination.nomination_approved = "Y" AND nomination.nomination_locked = "N" 
') or die('tallyScores(nominationTable): ' . mysql_error()); 

每个表的 “_BAK” 部分只是表明我测试了这个在我的表的备份副本上。