2016-02-04 26 views
5

は私が値デクリメント小さな声明があります。1つのSQLクエリでSELECT、UPDATE、DELETE?

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

をしかし、その値が減少した後、0になるとSQLが行を削除することが可能でしょうか?もしそうなら、私はそのカートに一致する行の数を詳述します:

SELECT FROM cart_items WHERE cart_id = {$cart_id} 

と行の数がゼロであれば、私はそうのように、別のテーブルからそのレコードを削除する:

DELETE FROM cart WHERE id = {$cart_id} 

これを行うにはいくつかのクエリが必要なようですが、すべてを単一のSQL文で実行できるかどうかを確認してください。

+4

ストアドプロシージャが必要です。 –

+1

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の速度を上げるために使用できる識別子が含まれていますが、それらは無ければ問題ありません。他の数量のアイテムや空のカートを探すだけです。

+1

しかし、それは単一のクエリではありません... –

+0

いいえ、どちらもストアドプロシージャ..それはちょうど1つの呼び出しでラップされています。 – Arth

+1

それは解決策になるかもしれませんが、@daninthemixが何を期待しているのか正確には考えていません。 –

0

私はあなたがエラー届きますので、あなたは、トリガーを使用します場合でも、1つのクエリでこのすべてを行うことが可能ではないと思われる:あなたが更新クエリを実行する場合

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. 

...

関連する問題