【问题标题】:Simplify update-statement简化更新语句
【发布时间】:2013-08-22 15:05:42
【问题描述】:

我有闲置的更新声明:

update tmp set 
tmp.Anzahl=(select sum(a.BNANZ) from PAYMASTER_Journal a where a.BNARTID=tmp.ArtikelAutoID), 
tmp.Betrag=(select sum(a.BNBETR) from PAYMASTER_Journal a where a.BNARTID=tmp.ArtikelAutoID), 
tmp.Rabatt=(select sum(a.BNRMRBETR) from PAYMASTER_Journal a where a.BNARTID=tmp.ArtikelAutoID) 
from ##tmp1 tmp 

这样,对于##tmp1 中的每条记录,都会执行3 个子查询。 ##tmp1 包含 10'000 条记录 -> 总共 30'000 个子查询。

因为每个子查询都从 PAYMASTER_Journal 中选择相同的记录,所以我正在寻找一种方法来更新 ##tmp1,同时在 ##tmp1 中的每条记录只执行一个子查询。

希望有人能帮我解决这个问题。

【问题讨论】:

    标签: sql sql-server-2008 sql-update


    【解决方案1】:

    使用LEFT JOIN 试试这个

    update tmp set 
    tmp.Anzahl=BNANZ_accumulated, 
    tmp.Betrag=BNBETR_accumulated, 
    tmp.Rabatt=BNRMRBETR_accumulated
    from ##tmp1 tmp 
    LEFT JOIN  ( SELECT BNARTID, 
                    SUM(BNANZ) AS BNANZ_accumulated, 
                    SUM(BNBETR) AS BNBETR_accumulated,
                    SUM(BNRMRBETR) AS BNRMRBETR_accumulated 
                    FROM PAYMASTER_Journal 
                    WHERE (ARTIKELAUSWAHL=0x30 AND BLBONSTO=0x30 AND BLZESTO=0x30 AND 
                          STORNO=0x30 AND 
                          BDDAT BETWEEN '20120301' AND '20130821' AND 
                          AdressID='d68e4d8f-e60e-4482-9730-76076948df43' AND
                          BNFIL=5 AND 
                          ISNULL(Preisliste, 'VK-Preisliste') =  'VK-Preisliste' AND 
                          BNARTID=tmp.ArtikelAutoID) 
    
                    GROUP BY BNARTID) a ON a.BNARTID=tmp.ArtikelAutoID
    

    PAYMASTER_Journal 中没有给定##tmp1.ArtikelAutoID 的行时,这将留下您NULL

    如果您不想触摸它们,请将LEFT JOIN 更改为INNER JOIN

    【讨论】:

    • 还有一个问题:在我的示例中,子选择的有效位置要复杂得多。它是: (ARTIKELAUSWAHL=0x30 AND BLBONSTO=0x30 AND BLZESTO=0x30 AND STORNO=0x30 AND BDDAT>='20120301' AND BDDAT
    • @ThomasKehl 类似于编辑后的回复? 我是 where 子句用于表 PAYMASTER_Journal
    • 是的。不,我想我明白了:由于##tmp1 和 PAYMASTER_Journal 之间的关联,需要 group by?
    • 组是用来获取两个表之间的关系的,是和否是什么意思...我应该计算为IF(1 = 0)吗?
    • 我的意思是“我在哪里......” - 而另一个不应该是“不,......” - 而是:“现在......”
    【解决方案2】:

    我会选择MERGE 声明:

    merge ##tmp1
    using   (select 
                BNARTID
                ,sum(BNANZ) as BNANZ
                ,sum(BNBETR) as BNBETR
                ,sum(BNRMRBETR) as BNRMRBETR
            from 
                PAYMASTER_Journal
            group by
                BNARTID
            ) as upd
    on tmp.ArtikelAutoID = upd.BNARTID
    when matched then update set Anzahl=BNANZ, Betrag=BNBETR, Rabatt=BNRMRBETR;
    

    【讨论】:

      【解决方案3】:

      您可以使用单个子查询来执行此操作,如下所示。

      UPDATE  tmp T 
      INNER JOIN
              (SELECT a.BNARTID
                      ,sum(a.BNANZ) as BANAZ_SUM
                      ,sum(a.BNBETR) as BNBETR_SUM
                      ,sum(a.BNRMRBETR) as BNRMRBETR_SUM
              FROM    PAYMASTER_Journal a
              WHERE   a.BNARTID = tmp.ArtikelAutoID
              GROUP BY
                      a.BNARTID
              ) SQ
      ON      SQ.BNARTID = tmp.ArtikelAutoID       
      SET     tmp.Anzahl = SQ.BANAZ_SUM
              ,tmp.Betrag = SQ.BNBETR_SUM
              ,tmp.Rabatt = SQ.BNRMRBETR_SUM
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-23
        • 2012-03-22
        • 1970-01-01
        • 2015-09-12
        • 1970-01-01
        相关资源
        最近更新 更多