2016-02-04 45 views
5

我有递减值的微小声明:选择,更新,删除一个SQL查询?

UPDATE cart_items SET quantity = quantity - 1 
WHERE cart_id = {$cart_id} AND id = {$cart_item_id} 

但是,这将有可能为SQL删除行如果递减后,该值变为0?如果是这样,我当时想讲述匹配车的行数:

SELECT FROM cart_items WHERE cart_id = {$cart_id} 

如果行数是零,我想从另一个表中删除记录,像这样:

DELETE FROM cart WHERE id = {$cart_id} 

目前看起来好像需要几次查询才能做到这一点,但这一切都可以在单个SQL语句中完成吗?

+4

您将需要一个存储过程。 –

+1

这是不可能在一个查询。 – rbedger

回答

2

简短的回答是,如果没有在触发器或过程中包含额外的查询,这是不可能的。

为此,您可以在一个事务,并没有SELECT,但它会采取3个查询:

START TRANSACTION; 

    UPDATE cart_items 
     SET quantity = quantity - 1 
    WHERE cart_id = {$cart_id} 
     AND id = {$cart_item_id}; 

    DELETE 
     FROM cart_items 
    WHERE quantity = 0 
     AND cart_id = {$cart_id} 
     AND id = {$cart_item_id}; 

    DELETE c 
     FROM cart c 
LEFT JOIN cart_items ci 
     ON ci.cart_id = c.id 
    WHERE c.id = {$cart_id} 
     AND ci.cart_id IS NULL; 

COMMIT; 

最后DELETE加入购物车到cart_items,如果没有找到(cart_items场删除车是NULL)。

我已经包含了可用的标识符来加速DELETE,虽然它们在没有它们的情况下应该没问题..它只会查找和拾取任何其他数量为0的物品或空购物车。

+1

但它不是一个单一的查询... –

+0

不,但既不是一个存储过程..它只是在一次调用中结束。 – Arth

+1

它可以是解决方案,但我想这不是什么@daninthemix期望... –

0

我认为这是不可能做到这一切在一个查询中,即使你将使用触发器,因为您会收到错误:

CREATE TABLE cart_items (cart_id int key, quantity int); 
INSERT INTO cart_items VALUES (1, 1), (2, 2); 
-- Create trigger 
delimiter | 
CREATE TRIGGER update_cart_items AFTER UPDATE ON cart_items 
    FOR EACH ROW 
    BEGIN 
    DELETE FROM cart_items WHERE quantity = 0; 
    END; 
| 
delimiter ; 

现在,如果你运行更新查询:

UPDATE cart_items SET quantity = quantity - 1 WHERE cart_id = 1; 

您会收到错误:

ERROR 1442 (HY000): Can't update table 'cart_items' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

这就是为什么我认为你应该使用几个查询......