MySQL:如何在更新值时使此子查询工作?

时间:2016-04-05 22:30:54

标签: mysql select sql-update rollback

我正在尝试编写一个列出商品ID,标题,旧价格和新价格的查询。我不能做更新声明因为那时我认为我不能列出旧价格。

INSTRUCTION:

  

使用子订单将“疲惫不得”的所有商品价格提高10%。显示之前和之后的价格。之后回滚。

根据指示,此作业有三个主要目标: 1.显示旧价格。 2.使用子查询通过计算显示新价格。 3.完成后使用回滚。

问题: 是否可以将UPDATE放在SELECT语句中,如子查询? (答案显然不是。)

我遇到问题的地方:

UPDATE items
SET unit_price = ROUND(unit_price + (unit_price * .10),2) as 'New Price'
WHERE item_id = 
    (SELECT item_id as 'Item ID',
              title as 'Title',
              unit_price as 'Old Price', --Except this won't work because the unit price is now the new price...
    FROM items
    WHERE title = 'No Rest for the Weary'
    );        

这就是我现在所拥有的,但ROLLBACK位让我卡住了。在这种情况下,人们会把它放在哪里?或者我完全误解了这些指示?

  SELECT item_id as 'Item ID', title as 'Title', unit_price as 'Price',
    ROUND(unit_price + (unit_price * .10),2) as 'New Price'
FROM items
WHERE item_id =
    (SELECT item_id 
    FROM items
    WHERE title = 'No Rest for the Weary'
    );

1 个答案:

答案 0 :(得分:1)

不,在UPDATE语句中包含SELECT语句是不可能的。但是可以在SELECT内包含UPDATE

为什么需要UPDATE声明?意图更新表中的列是否具有新值,因此新值是否持久存在?

或者,是否意图返回结果集? UPDATE语句不会像SELECT语句那样返回结果集。

问题中的UPDATE语句不起作用,因为子查询返回了三列。在上下文中使用

col IN (subquery)

子查询应该只返回一列。返回两列或更多列无效。

您可以编写一个返回表达式结果的SELECT语句。在此示例中,新单位价格比当前unit_price增加10%......

SELECT i.item_id                 AS `item_id`
     , i.title                   AS `title`
     , i.unit_price              AS `old_unit_price`
     , ROUND(i.unit_price*1.1,2) AS `new_unit_price`
  FROM items i
 WHERE i.title = 'No Rest for the Weary'
 ORDER BY i.item_id

如果返回了您想要的结果,并且您希望在UPDATE中使用该结果为unit_price列分配新值,则假设item_id是PRIMARY或UNIQUE KEY在items表格上......

UPDATE ( SELECT r.*
           FROM ( -- select statement above goes here 
                  SELECT i.item_id                 AS `item_id`
                       , i.title                   AS `title`
                       , i.unit_price              AS `old_unit_price`
                       , ROUND(i.unit_price*1.1,2) AS `new_unit_price`
                    FROM items i
                   WHERE i.title = 'No Rest for the Weary'
                ) r
        ) s
   JOIN items t
     ON t.item_id = s.item_id
    SET t.unit_price = s.new_unit_price

再次强调一点,这假设item_iditems表上的PRIMARY KEY(或非NULL UNIQUE KEY)。

UPDATE语句之后,重新运行原始SELECT查询将返回不同的结果(假设原始unit_price充分大于零。)

<强>后续

  1. 创建显示旧价格的查询
  2. 上面答案中的第一个SELECT显示“旧价格”(假设“旧价格”存储在unit_price列中。)

    1. 将价格更改为比当前价格高10%。
    2. 上面答案中的第一个SELECT显示向unit_price列添加10%,四舍五入到小数点后的两位数,作为另一列new_unit_price返回。

      1. 使用子查询
      2. 第一个查询不使用子查询。但我们可以轻松添加一个。 (我不明白为什么我们需要添加一个不必要的子查询。这个子查询返回的是什么,我们可以在SELECT列表中使用子查询,或者在WHERE子句中,内联视图是否有资格作为子查询?)< / p>

        此版本在SELECT列表中添加了两个不必要的相关子查询,一个不必要的内联视图,以及WHERE子句中不必要的子查询。

        SELECT i.item_id                 AS `item_id`
             , ( SELECT t.title
                   FROM items t
                  WHERE t.item_id = i.item_id
                 ORDER BY t.title
                 LIMIT 1
                )                        AS `title`
             , ( SELECT p.unit_price
                   FROM items p
                  WHERE p.item_id = i.item_id
                 ORDER BY p.unit_price
                 LIMIT 1
               )                         AS `old_unit_price`
             , ROUND(i.unit_price*1.1,2) AS `new_unit_price`
          FROM items i
         CROSS
          JOIN ( SELECT 1 AS i ) i
         WHERE i.title = (SELECT 'No Rest for the Weary')
         ORDER BY i.item_id
        

        UPDATE语句的更简单版本(向unit_price添加10%)也不需要子查询。

        UPDATE items t
           SET t.unit_price = ROUND(t.unit_price*1.1,2)
         WHERE t.title = 'No Rest for the Weary'
        

        同样,UPDATE语句不可能返回结果集。