По какой-то причине этот триггер не обновляет таблицу заказов, что я делаю неправильно?

DELIMITER $$

/*!50003 DROP TRIGGER*//*!50032 IF EXISTS */ /*!50003 `orderTotalInsert` */$$

/*!50003 CREATE */ /*!50017 DEFINER = 'root'@'localhost' */ /*!50003 TRIGGER `orderTotalInsert` 
    AFTER INSERT ON `orderitem` FOR EACH ROW 
    BEGIN
     UPDATE `Order`
    INNER JOIN (
        select orderitemID, SUM(orderitem.UnitPrice) sum_price
        from orderitem 
        group by orderitemID
    )  t on t.orderitemID = order.OrderId 
    SET  Order.TotalAmmount = t.sum_price;
    END */$$


DELIMITER ;
1
Seth Pritchard 20 Сен 2018 в 20:46

2 ответа

Лучший ответ
select orderitemID, SUM(orderitem.UnitPrice) sum_price
from orderitem 
group by orderitemID

Он группируется по orderitemID, который, как я полагаю, является первичным ключом таблицы orderitem. Поскольку вы группируете по уникальному столбцу, «группы» всегда представляют собой группы по 1, а «сумма» всегда равна каждому отдельному значению удельной цены.

Эффект состоит в том, что ваше ОБНОВЛЕНИЕ перезаписывает TotalAmmount несколько раз и получает последнюю единичную цену вместо суммы всех единичных цен для заказа.

Вы должны группироваться по orderID, чтобы получить общую сумму для всех элементов заказа, принадлежащих одному заказу.

select orderID, SUM(orderitem.UnitPrice) sum_price
from orderitem 
group by orderID

Вторая проблема: вам не нужно обновлять все заказы каждый раз, когда вы вставляете элемент заказа. Вам просто нужно обновить общую сумму для одного заказа, для элемента заказа, который вы вставляете. Поэтому вам следует ограничить подзапрос строками WHERE orderID = NEW.orderID.

CREATE DEFINER = 'root'@'localhost' TRIGGER `orderTotalInsert` 
AFTER INSERT ON `orderitem` FOR EACH ROW 
BEGIN
 UPDATE `Order`
 INNER JOIN (
    SELECT orderID, SUM(orderitem.UnitPrice) sum_price
    FROM orderitem
    WHERE orderID = NEW.orderID
    GROUP BY orderID
 )  t on t.orderID = order.OrderId 
 SET Order.TotalAmmount = t.sum_price;
END
1
Bill Karwin 20 Сен 2018 в 18:06

Действительно ли сравнение с t.orderitemId = order.OrderId правильным? Похоже, что подзапрос будет группироваться на собственном orderid, который ссылается на Order.

В качестве альтернативы, если бы мои предположения были правильными и есть похожие триггеры UPDATE и DELETE, вы могли бы упростить и снизить стоимость этого триггера, используя вместо этого этот запрос на обновление.

UPDATE `Order` SET TotalAmmount = TotalAmmount + NEW.UnitPrice WHERE OrderId = NEW.OrderId;

Для ТРИГГЕРА ОБНОВЛЕНИЯ будет SET TotalAmmount = TotalAmmount + NEW.UnitPrice - OLD.UnitPrice

Для УДАЛЕНИЯ ТРИГГЕРА будет SET TotalAmmount = TotalAmmount - OLD.UnitPrice

0
Uueerdo 20 Сен 2018 в 18:00