2012-05-21 4 views
0

테이블 carts 및 이 있으며 두 번째 테이블에는 외래 키가 있습니다. 이제 carts에서 3 개월 이상이고 관련이없는 모든 행을 삭제하고 싶습니다. cartitems 다음 쿼리는 나에게 정확한 결과 제공 :JOIN, GROUP BY 및 HAVING이있는 테이블에서 삭제

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 만 개 행이 있기 때문에, 나는 쿼리가 작동합니다 존재

답변

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 
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 또는 다른 값으로 바꿀 수 있습니다.

두 번째 시도 : 그 ID에 관련된

하나의 ID 목록 (내가 c.id가 기본 키입니다 희망)을 생성하는
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); 

및 삭제 모든 행.

+0

내가이 오류 메시지가 : "# 1093 - 당신은 목표 테이블 '카트'를 지정할 수 없습니다 업데이트 FROM 절에" –

+0

@BenjaminWohlwend는'보기를 carts'입니까? 아니면 관련된 테이블에 트리거가 있습니까? – rekire

+0

아니요, 관련된 두 테이블 모두 MyISAM 테이블입니다. –

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 
); 

으로 시도 할 수