2010-08-12 73 views
25

我有3个表(简体):SQL服务器更新加入

tblOrder(OrderId INT) 
    tblVariety(VarietyId INT,Stock INT) 
    tblOrderItem(OrderId,VarietyId,Quantity INT) 

如果我下订单,我用这个下降的库存水平:

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 

一切都很好,直到有tblOrderItem中的两行与同一OrderId的VarietyId相同。在这种情况下,只有一个行用于库存更新。它似乎在某种程度上做了GROUP BY VarietyId。

任何人都可以点亮一下吗?非常感谢。

+0

应该不可能有相同的品种/订购组合? 也就是说,如果一个订单的同一品种出现大于1,那么这是在数量列中捕获的,而不是多行? – gbn 2010-08-12 13:19:15

+0

技术上,是的。但也有其他列tblOrderItem这意味着多条线可以进入这些相同的基本数字(例如日期字段) – Geoff 2010-08-12 13:29:11

回答

43

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

当您有多个行时,SQL Server将arbritrarily选择其中一个进行更新。

如果是这样的话,你需要组第一

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 

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

+0

非常感谢gbn - 这对我来说... – Geoff 2010-08-12 13:46:21

+0

+1工作它所有的办法。 – Tobiasopdenbrouw 2010-08-12 13:49:29

+1

+100 @gbn我欠你一杯啤酒。 – 2013-04-10 04:53:19

1

您正在更新。它会更新一次。

编辑:为了解决,你可以添加一个子查询,它将你的订单项由orderid和varietyid分组在一起,并与金额相加。

12

从文档UPDATE

UPDATE语句的结果是 未定义如果语句包括一 来自未在 这样一种方式,只有一个值是 可用于每个列发生 被更新指定条款(换言之,如果 UPDATE语句不是 确定性)。例如,给出以下 脚本 UPDATE语句,在表S =两行满足FROM子句 资格在 UPDATE语句,但它是 不确定它从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