UPDATE FROM在整个表上运行

时间:2013-06-28 08:02:19

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

我尝试在记录列表上运行更新,并根据一些计算修改列。这是我的查询(我的查询实际上将金额重新分配到NET和VAT):

update transaction_details
set amount = (
    CASE WHEN id = x.netID THEN x.calculated_NET
         WHEN id = x.vatID THEN x.calculated_VAT
    END
    )
from
    (select
        d1.id as 'netHmy',
        d2.id as 'vatHmy',
        round(((d1.amount + d2.amount )/1.18) * 0.18, 2) 'calculated_VAT',
        round((d1.amount + d2.amount )/1.18, 2) 'calculated_NET'
    from transaction_details d1 join transaction_details d2 on d1.id = d2.netID
    where
        1 = 1
        -- multiple conditions
                              ) as x

选择到X表中的记录是175,但是当我运行此查询时,它会遍历整个transaction_details表(超过4.000.000条记录)。

我知道查询中的操作顺序是

1. FROM clause
2. WHERE clause
3. GROUP BY clause
4. HAVING clause
5. SELECT clause
6. ORDER BY clause

所以我期望更新的结果被限制在选定的175条记录中,但显然它会覆盖整个表格,结果为4.354.665 rows affected

UPDATE语句中的操作顺序是否不同,或者我应该重新设计我的查询?

1 个答案:

答案 0 :(得分:3)

如果您希望应用任何应用过滤器,则需要在FROM子句中直接引用要更新的表。类似的东西:

update d1 --Or d2?
set amount = (
    CASE WHEN id = d1.netID /*?*/ THEN round((d1.amount + d2.amount )/1.18, 2)
         WHEN id = d1.vatID /*?*/ THEN round(((d1.amount + d2.amount )/1.18) * 0.18, 2)
    END
    )
from
   transaction_details d1 join transaction_details d2 on d1.id = d2.netID
where
    1 = 1
  -- multiple conditions

我不确定netIDvatID实际意图来自哪里,因为您没有在嵌套SELECT中显示它们,我猜测了要更新的表是d1别名而不是d2。您可以根据上述内容进行调整,以达到您的实际要求。