我有一个表carts
和cartitems
,第二个有第一个的外键。现在,我想删除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
表中有大约1000万行,我要感谢有关如何改进此查询的建议: - )
答案 0 :(得分:1)
您可以在不使用LIMIT
或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
答案 1 :(得分: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或任何其他值来交换星号。
第二次尝试:
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相关的所有行。
答案 2 :(得分: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
);
虽然我不确定:)