【问题标题】:SQL Server Update with Inner Join带有内部联接的 SQL Server 更新
【发布时间】:2011-03-28 22:27:18
【问题描述】:

我有 3 张表(简化版):

 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 中有两行具有相同的 VarietyId 用于相同的 OrderId。在这种情况下,只有其中一行用于库存更新。它似乎正在以某种方式在其中进行 GROUP BY VarietyId。

谁能解释一下?非常感谢。

【问题讨论】:

  • 应该不可能有相同的品种/订单组合?也就是说,如果一个订单的同一个品种出现 >1,那么这被捕获在数量列中,而不是多行?
  • 从技术上讲,是的。但是 tblOrderItem 中还有其他列,这意味着可以使用相同的基本数字(例如日期字段)进入多行

标签: sql sql-server-2005 tsql join


【解决方案1】:

来自文档UPDATE

UPDATE 语句的结果是 如果语句包含一个未定义的 中未指定的 FROM 子句 这样只有一个值是 可用于每列出现 即被更新(换句话说,如果 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

【讨论】:

    【解决方案2】:

    我的猜测是,因为您向我们展示了简化的架构,所以缺少一些信息来确定为什么给定 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  
    

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

    【讨论】:

      【解决方案3】:

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

      编辑:要解决这个问题,您可以添加一个子查询,该子查询将按 orderid 和品种 ID 对您的订单项进行分组,并加上金额的总和。

      【讨论】:

        猜你喜欢
        • 2011-08-14
        • 2017-01-25
        • 2012-03-24
        • 2011-04-21
        • 1970-01-01
        • 2011-12-23
        • 2012-10-04
        • 2015-03-17
        • 2014-06-09
        相关资源
        最近更新 更多