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

How to update attribute based on result of aggregate function

我是 mySQL 的新手。 我想根据零售价和订购产品的数量更新 table 的订单价格。我有以下 tables(针对此问题进行了简化):

Products:

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 并且它以自己的 table 输出。但是我想更新属性Sales_orders.Order_price,而不是在table中调出订单价格。

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 中插入新行时,这个 returns 出错了。

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 ;

返回错误:

Error Code: 1222. The used SELECT statements have a different number of columns

希望有人能帮忙吗?

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

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           |

Sales_products:

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

Sales_orders:

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

现在,触发器就位后,我们在 Sales_items table 中插入一条与相同 sales_order:

相关的新记录
insert into Sales_products values(1, 2, 10);

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

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

这是一个触发器,所以我希望它使用 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 触发器。这就是计算这些值 "on-the-fly" 比使用触发器维护它们更简单的原因。