Обновление SQL Server с помощью Inner Join
У меня есть 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
Мое предположение заключается в том, что, поскольку вы показали нам упрощенную схему, отсутствует какая-то информация, которая определяла бы причину повторяющихся значений 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
Если нет, то таблица OrderItems PK неверна, потому что если разрешает дублировать комбинации OrderID/VarietyID (PK должен быть OrderID/VarietyID, или они должны быть ограничены уникальными)
Ответ 2
Из документации UPDATE
Результаты инструкции UPDATE: undefined, если инструкция содержит FROM, которое не указано в таким образом, что только одно значение доступно для каждого столбца который обновляется (другими словами, если утверждение UPDATE не детерминированный). Например, учитывая UPDATE в следующем script, обе строки в таблице s соответствуют квалификации предложения FROM в инструкция UPDATE, но это undefined какая строка из 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
Ответ 3
Вы делаете обновление. Он будет обновляться один раз.
Изменить: чтобы решить, вы можете добавить в подзапрос, который будет группировать ваши orderitems посредством orderid и multipleid с суммой суммы.