如何根据聚合函数的结果更新属性

时间:2019-04-07 13:14:05

标签: mysql sql database-trigger

我是mySQL的新手。 我想根据零售价和所订购产品的数量来更新表格的订购价格。我有下表(此问题的简化版):

ProductID Retail_price

Sales_orders

SalesOrdersID Order_price //This is the derived attribute that I want to update when the below Sales_products table is updated.

Sales_products

SalesOrdersID ProductID Quantity

Order_price

以下代码的工作方式是,我得到了正确的Sales_orders.Order_price,并在自己的表中输出。但是我想更新属性SELECT sales_product.SalesOrdersID, SUM(Quantity * Retail_price) as "Total price of order" FROM sales_product LEFT JOIN products ON sales_product.ProductID = products.ProductID GROUP BY sales_product.SalesOrdersID ,而不是在表中标注订单价格。

Sales_orders

我也尝试了触发器,但是当我尝试在CREATE trigger find_order_price2 AFTER INSERT ON Sales_products FOR EACH ROW BEGIN DECLARE price int; SELECT sales_product.SalesOrdersID, SUM(Quantity * Retail_price) INTO price FROM sales_product LEFT JOIN products ON sales_product.ProductID = products.ProductID; UPDATE sales_orders set Order_price = price; END; $$ DELIMITER ; 中插入新行时,这会返回错误。

-ignorewarnings

返回错误:

  

错误代码:1222。使用的SELECT语句具有不同的列数

希望有人可以提供帮助吗?

2 个答案:

答案 0 :(得分:0)

以下触发代码应该可以完成工作:

DELIMITER $$
CREATE trigger update_sales_order_price
AFTER INSERT ON Sales_products
FOR EACH ROW
BEGIN

    UPDATE Sales_orders so
    SET Order_price = (
        SELECT SUM(sp.Quantity * p.Retail_price)
        FROM Sales_products sp
        INNER JOIN Products p ON p.ProductID  = sp.ProductID 
        WHERE sp.SalesOrdersID = so.SalesOrdersID
    )
    WHERE SalesOrdersID = NEW.SalesOrdersID;

END;
$$
DELIMITER;

Demo on DB Fiddle

请考虑以下布局:

产品:

| ProductID | retail_price |
| --------- | ------------ |
| 1         | 10           |
| 2         | 20           |

销售产品:

| SalesOrdersID | ProductID | Quantity |
| ------------- | --------- | -------- |
| 1             | 1         | 10       |

销售订单:

| SalesOrdersID | Order_price |
| ------------- | ----------- |
| 1             | 100         |

现在,有了触发器,我们在Sales_items表中插入与相同sales_order相关的新记录:

insert into Sales_products values(1, 2, 10);

插入后,这是Sales_orders表的(更新的)内容:

| SalesOrdersID | Order_price |
| ------------- | ----------- |
| 1             | 300         |

答案 1 :(得分:0)

这是一个触发器,所以我希望它正在使用newold

这通常是逐步进行的:

CREATE trigger trig_sales_products_update_price
AFTER INSERT ON Sales_products
FOR EACH ROW
BEGIN
    UPDATE sales_order so JOIN
           product p
           ON p.product_id = new.product_id
        SET so.order_price = so.order_price + new.quantity * p.retail_price
        WHERE so.SalesOrderId = new.SalesOrderId
END;
$$
DELIMITER ;

如果愿意,您可以重新计算整个值:

CREATE trigger trig_sales_products_update_price
AFTER INSERT ON Sales_products
FOR EACH ROW
BEGIN
    UPDATE sales_order so JOIN
           (SELECT sp.SalesOrderId,
                   SUM(sp.quantity * p.retail_price) as new_total
            FROM sales_products sp
                 product p
                 ON p.product_id = sp.product_id
            WHERE sp.SalesOrderId = new.SalesOrderId
            GROUP BY sp.SalesOrderId
           ) sp
           ON so.SalesOrderId = sp.SalesOrderId
        SET so.order_price = sp.new_total
END;
$$
DELIMITER ;

但是,触发器通常以增量方式完成。

请记住,如果执行此操作,则还需要updatedelete触发器。这就是为什么比使用触发器来维护它们更容易“即时”计算这些值的原因。