【问题标题】:Update multiple values in a single statement在单个语句中更新多个值
【发布时间】:2010-09-22 06:42:47
【问题描述】:

我有一个主/明细表,并想根据明细表更新主表中的一些汇总值。我知道我可以这样更新它们:

update MasterTbl set TotalX = (select sum(X) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID)
update MasterTbl set TotalY = (select sum(Y) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID)
update MasterTbl set TotalZ = (select sum(Z) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID)

但是,我想在一个语句中完成,如下所示:

update MasterTbl set TotalX = sum(DetailTbl.X), TotalY = sum(DetailTbl.Y), TotalZ = sum(DetailTbl.Z)
from DetailTbl
where DetailTbl.MasterID = MasterTbl.ID group by MasterID

但这不起作用。我也尝试过省略“group by”子句的版本。 我不确定我是否遇到了我的特定数据库 (Advantage) 的限制,或者我的 SQL 的限制。大概是后者。有人可以帮忙吗?

【问题讨论】:

    标签: sql advantage-database-server


    【解决方案1】:

    为什么要对更新语句进行分组?您确定这不是导致查询失败的部分吗?试试这个:

    update 
        MasterTbl
    set
        TotalX = Sum(DetailTbl.X),
        TotalY = Sum(DetailTbl.Y),
        TotalZ = Sum(DetailTbl.Z)
    from
        DetailTbl
    where
        DetailTbl.MasterID = MasterID
    

    【讨论】:

    • @Chris,这对我也不起作用。如果它对你有用,那么我可能遇到了我的特定数据库的限制。
    • 我现在已经澄清了我原来的问题,表明我已经尝试省略“group by”子句。谢谢!
    • 您使用的是什么数据库服务器/版本?当您说我的 SQL 时,您是指“我的 SQL 技能”还是“mySQL,服务器”?
    • 没关系,我看到你说优势。我没有测试框,否则我会尝试为您找到一个有效的查询。对不起:(
    【解决方案2】:

    您是否尝试过为每个字段设置子查询:

    UPDATE
        MasterTbl
    SET
        TotalX = (SELECT SUM(X) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID),
        TotalY = (SELECT SUM(Y) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID),
        TotalZ = (SELECT SUM(Z) from DetailTbl where DetailTbl.MasterID = MasterTbl.ID)
    WHERE
        ....
    

    【讨论】:

    • @Milen,你说得对,那会奏效。但是,我认为它不会比我的示例中的三个语句快。我想我应该尝试两种方式并比较时间。
    【解决方案3】:

    试试这个:

     Update MasterTbl Set
        TotalX = Sum(D.X),    
        TotalY = Sum(D.Y),    
        TotalZ = Sum(D.Z)
     From MasterTbl M Join DetailTbl D
        On D.MasterID = M.MasterID
    

    根据您使用的数据库,如果这不起作用,那么试试这个(这是非标准 SQL,但在 SQL Server 中是合法的):

     Update M Set
        TotalX = Sum(D.X),    
        TotalY = Sum(D.Y),    
        TotalZ = Sum(D.Z)
     From MasterTbl M Join DetailTbl D
         On D.MasterID = M.MasterID
    

    【讨论】:

    • 我尝试了您的两种方法,但都无法正常工作。我的数据库只支持带有一些扩展的 SQL-92。您使用什么数据库支持您建议的代码?
    • SQL Server 支持此语法...如果您的数据库不支持此语法,那么我认为您会坚持使用多子查询方法.. 如下 Milen 推荐的那样
    • 这不是合法的 SQL。更新中没有“FROM”子句。 dev.mysql.com/doc/refman/6.0/en/update.html
    • +1 Charles - 当我开始问自己的问题时,我偶然发现了这个问题 - 以及你的答案。我在这里对你投了赞成票,因为你刚刚让我摆脱了一个艰难的 SQL 情况。感谢您在更新中显示“From”语法!
    【解决方案4】:

    试试这个:

    update MasterTbl M,
           (select sum(X) as sX,
                   sum(Y) as sY,
                   sum(Z) as sZ,
                   MasterID
            from   DetailTbl
            group by MasterID) A
    set
      M.TotalX=A.sX,
      M.TotalY=A.sY,
      M.TotalZ=A.sZ
    where
      M.ID=A.MasterID
    

    【讨论】:

      【解决方案5】:

      在 Oracle 中,解决方案是:

      UPDATE
          MasterTbl
      SET
          (TotalX,TotalY,TotalZ) =
            (SELECT SUM(X),SUM(Y),SUM(Z)
               from DetailTbl where DetailTbl.MasterID = MasterTbl.ID)
      

      不知道你的系统是否允许。

      【讨论】:

      • 我的数据库不允许这样做,但很高兴看到其他数据库供应商采用的方法。
      【解决方案6】:

      如果您的数据库支持它,如果通过 LAN 查询,将所有 3 个更新连接到一个 sql 字符串将节省服务器往返行程。因此,如果没有其他工作,这可能会给您带来轻微的改善。典型的'多语句分隔符是分号,例如:

      'update x....;update y...;update...z'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-07
        相关资源
        最近更新 更多