内部联接的SQL Server更新

Geo*_*off 25 sql t-sql join sql-server-2005

我有3个表(简化):

 tblOrder(OrderId INT)  
  tblVariety(VarietyId INT,Stock INT)  
  tblOrderItem(OrderId,VarietyId,Quantity INT)
Run Code Online (Sandbox Code Playgroud)

如果我下订单,我会使用以下方式降低库存水平:

UPDATE tblVariety  
SET tblVariety.Stock = tblVariety.Stock - tblOrderItem.Quantity  
FROM tblVariety  
INNER JOIN tblOrderItem ON tblVariety.VarietyId = tblOrderItem.VarietyId  
INNER JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId  
WHERE tblOrder.OrderId = 1
Run Code Online (Sandbox Code Playgroud)

一切正常,直到tblOrderItem中有两行,同一个OrderId具有相同的VarietyId.在这种情况下,只有一行用于库存更新.似乎在某种程度上在那里做了一个GROUP BY VarietyId.

任何人都能解释一下吗?非常感谢.

gbn*_*gbn 43

我的猜测是,因为你已经向我们展示了简化的模式,所以缺少一些信息来确定为什么具有给定OrderID的重复VarietyID值.

当您有多行时,SQL Server将自行选择其中一行进行更新.

如果是这种情况,则需要先进行分组

UPDATE V
SET
   Stock = Stock - foo.SumQuantity
FROM
    tblVariety V
    JOIN
    (SELECT SUM(Quantity) AS SumQuantity, VarietyID
     FROM tblOrderItem
      JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId  
     WHERE tblOrder.OrderId = 1
     GROUP BY VarietyID
    ) foo ON V.VarietyId = foo.VarietyId  
Run Code Online (Sandbox Code Playgroud)

如果没有,那么OrderItems表PK是错误的,因为如果允许重复的OrderID/VarietyID组合(PK应该是OrderID/VarietyID,或者这些应该被约束为唯一的)


Adr*_*der 12

从文档 UPDATE

如果语句包含未以这样的方式指定的FROM子句,则UPDATE语句的结果是未定义的,即只有一个值可用于更新的每个列事件(换句话说,如果UPDATE语句不是确定性的).例如,给定以下脚本中的UPDATE语句,表s中的两行都满足UPDATE语句中FROM子句的限定条件,但未定义s中的哪一行用于更新表t中的行.

CREATE TABLE s (ColA INT, ColB DECIMAL(10,3))
GO
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3))
GO
INSERT INTO s VALUES(1, 10.0)
INSERT INTO s VALUES(1, 20.0)
INSERT INTO t VALUES(1, 0.0)
GO
UPDATE t 
SET t.ColB = t.ColB + s.ColB
FROM t INNER JOIN s ON (t.ColA = s.ColA)
GO
Run Code Online (Sandbox Code Playgroud)