SQL for Mere Mortals第4版 - 更新数据集

时间:2018-06-03 08:27:47

标签: mysql sql

我正在阅读本书并在第15章更新数据集中,在问题中为您解决部分存在以下问题:

“将配件的零售价格(类别= 1)设置为最高价供应商的批发价格加上35%”

我对作者提供此解决方案的原因感到有点困惑:

UPDATE Products 
SET 
RetailPrice = ROUND(1.35 * (
                    SELECT DISTINCT WholesalePrice
                    FROM Product_Vendors
                    WHERE Product_Vendors.ProductNumber = 
                          Products.ProductNumber
                        AND WholesalePrice = (
                                SELECT  MAX(WholesalePrice)
                                FROM Product_Vendors
                                WHERE Product_Vendors.ProductNumber = 
                                      Products.ProductNumber)),0)
WHERE RetailPrice < 1.35 * (
                SELECT DISTINCT WholesalePrice
                FROM Product_Vendors
                WHERE Product_Vendors.ProductNumber = Products.ProductNumber
                    AND WholesalePrice = (
                            SELECT MAX(WholesalePrice)
                            FROM Product_Vendors
                            WHERE Product_Vendors.ProductNumber = 
                                  Products.ProductNumber)
                            LIMIT 1)
AND CategoryID = 1;

...而不是:

UPDATE Products 
SET 
RetailPrice = ROUND(1.35 * (SELECT  MAX(WholesalePrice)
                            FROM Product_Vendors
                            WHERE Product_Vendors.ProductNumber = 
                                  Products.ProductNumber),0)
WHERE RetailPrice < 1.35 * (SELECT MAX(WholesalePrice)
                        FROM Product_Vendors
                        WHERE Product_Vendors.ProductNumber = 
                              Products.ProductNumber
                        LIMIT 1)
AND CategoryID = 1;

两者产生相同的结果,MySQL Workbench中受影响的行数相同......那么为什么呢?谢谢你们。

Sales Orders Modify Schema

1 个答案:

答案 0 :(得分:1)

很难推测作者选择此表格的原因。也许他们想对相关子查询提出一个观点。也许他们想要避免本书中没有介绍过的技巧。也许这是他们发生的第一件事,他们从来没有去过优化它。也许他们在编写带有某个MySQL版本功能的SQL时(没有100%肯定,我相信曾经是MySQL版本无法对子查询进行分组)。

这是另一种方法。我更喜欢这个,因为它很有效率。

UPDATE
    Products
    INNER JOIN (
        SELECT   ProductNumber, MAX(WholesalePrice) * 1.35 as RetailPrice
        FROM     Product_Vendors
        GROUP BY ProductNumber 
    ) Target ON Target.ProductNumber = Products.ProductNumber
SET
    Products.RetailPrice = ROUND(Target.RetailPrice, 0)
WHERE
    Products.CategoryID = 1
    AND Products.RetailPrise < Target.RetailPrice;