0

私はテーブルを持っておりcartscartitems2番目のテーブルには最初のテーブルへの外部キーがあります。cartsここで、3か月以上経過していて、関連する行がないすべての行を削除したいと思いますcartitems。次のクエリで正しい結果が得られます。

SELECT * 
FROM  `carts` c
LEFT OUTER JOIN  `cartitems` i ON (  `c`.`id` =  `i`.`cart_id` ) 
WHERE  `c`.`last_updated` < DATE_SUB(NOW() , INTERVAL 3 MONTH) 
GROUP BY  `c`.`id` 
HAVING COUNT(  `i`.`id` ) = 0;

しかし、このクエリをに変換する方法がわかりませんDELETE

また、cartsテーブルには最大1,000万行あるので、このクエリを改善する方法についての提案に感謝します:-)

4

3 に答える 3

1

以下を a なしLIMITで、または a と共にLIMIT実行して、行をバッチで削除できます。

DELETE c
FROM  carts c
WHERE c.last_updated < DATE_SUB(NOW() , INTERVAL 3 MONTH)
  AND NOT EXISTS
      ( SELECT *
        FROM cartitems i 
        WHERE c.id = i.cart_id
     ) 
LIMIT 10000 ;                           --- optional
于 2012-05-21T16:08:54.687 に答える
0

これで試すことができます

DELETE FROM 
(
    SELECT * 
    FROM  `carts` c
    LEFT OUTER JOIN  `cartitems` i ON (  `c`.`id` =  `i`.`cart_id` ) 
    WHERE  `c`.`last_updated` < DATE_SUB(NOW() , INTERVAL 3 MONTH) 
    GROUP BY  `c`.`id` 
    HAVING COUNT(  `i`.`id` ) = 0
);

私はそれについてはよくわかりません:)

于 2012-05-21T16:04:43.800 に答える
0

その存在するクエリは機能するはずです:

DELETE FROM `carts` WHERE EXISTS (SELECT * 
FROM  `carts` c
LEFT OUTER JOIN  `cartitems` i ON (  `c`.`id` =  `i`.`cart_id` ) 
WHERE  `c`.`last_updated` < DATE_SUB(NOW() , INTERVAL 3 MONTH) 
GROUP BY  `c`.`id` 
HAVING COUNT(  `i`.`id` ) = 0);

このクエリは、結果セット内のすべての行を削除する必要があります。

アスタリスクを null またはその他の値と交換できることに注意してください。

2 回目の試行:

DELETE FROM `carts` WHERE `carts`.`id` IN (SELECT `c`.`id` 
FROM  `carts` c
LEFT OUTER JOIN  `cartitems` i ON (  `c`.`id` =  `i`.`cart_id` ) 
WHERE  `c`.`last_updated` < DATE_SUB(NOW() , INTERVAL 3 MONTH) 
GROUP BY  `c`.`id` 
HAVING COUNT(  `i`.`id` ) = 0);

それはIDのリストを生成し(c.idが主キーであることを願っています)、そのIDに関連するすべての行を削除します。

于 2012-05-21T15:16:56.967 に答える