Обновление SQL Server с внутренним соединением - PullRequest
25 голосов
/ 12 августа 2010

У меня есть 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.

Может кто-нибудь пролить свет? Большое спасибо.

Ответы [ 3 ]

43 голосов
/ 12 августа 2010

Я предполагаю, что, поскольку вы показали нам упрощенную схему, отсутствует некоторая информация, которая бы определяла, почему повторяющиеся значения VarietyID для данного OrderID.

Если у вас несколько строк, 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  

Если нет, то таблица PK OrderItems неверна, поскольку, если допускает дублирование OrderID / VarietyIDкомбинации (PK должен быть OrderID / VarietyID, или они должны быть ограничены уникальными)

12 голосов
/ 12 августа 2010

Из документации UPDATE

Результаты оператора UPDATE не определены, если оператор содержит предложение FROM, которое не указано таким образом, чтобы толькоодно значение доступно для каждого экземпляра столбца, который обновляется (другими словами, если оператор UPDATE не является детерминированным). Например, с учетом оператора UPDATE в следующем сценарии обе строки в таблицах соответствуют квалификациямПредложение 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
1 голос
/ 12 августа 2010

Вы делаете обновление. Обновится один раз.

Изменить: чтобы решить, вы можете добавить в подзапрос, который будет группировать ваши элементы заказа по orderid и разновидности, с суммой на сумму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...