2017-05-10 5 views
0

동일한 열을 가진 두 개의 테이블을 가지고 있지만 행의 양이 다르면이 테이블에는 3 열의 복합 기본 키가 있습니다.DELETE 절이 SELECT 하위 쿼리가 반환하는 행보다 많은 행을 삭제합니다.

원래 table1은 테이블이고, table2는 데이터가 제거되었으므로 행이 적은 업데이트 된 테이블입니다. table1에는 있지만 table2에는없는 행을 반환하는 SELECT 문이 있습니다. 그러나 WHERE EXISTS를 사용하여 DELETE 절에 SELECT 문을 하위 쿼리로 넣을 때 하위 쿼리의 행뿐만 아니라 테이블 1의 모든 행을 삭제하려고합니다.

코드 :

DELETE FROM table1 
WHERE EXISTS(
SELECT t1.* 
FROM table1 AS t1 LEFT JOIN table2 AS t2 
ON (t1.compositekey1 = t2.compositekey1) 
AND (t1.compositekey2 = t2.compositekey2) 
AND (t1.compositekey3 = t2.compositekey3) 
WHERE (t2.compositekey1 IS NULL) AND 
(t2.compositekey2 IS NULL) AND (t2.compositekey3 IS 
NULL) 
); 

나는 독립 SELECT 쿼리와 하위 쿼리를 테스트는 110 행, 정확한 금액을 반환하지만, DELETE 쿼리에 넣어 때 모든 9600 개 행을 삭제하려고 위. 나는 WHERE EXISTS가 하위 쿼리에 의해 반환 된 가상 테이블에있는 행만 제거해야한다는 인상을 받고있었습니다.

INSERT 쿼리로 역방향 쿼리를 사용할 때 table1에없는 table2에있는 모든 행을 테이블 1에 삽입하면 제대로 작동합니다.

그래서 어디서 DELETE 문이 엉망인지 모르겠다.

내가 사용하려고 :

WHERE t1.compositekey1, t1.compositekey2, t1.compositekey3 IN (......) 

하지만 사용이 존재라고 오류가 발생합니다. 이것은 액세스 데이터베이스에서 사용되고 있으므로 SQL Server와 동일한 규칙이 적용됩니다.

미리 도움을 청하십시오.

답변

3

하위 쿼리가 상관되지 않고 적어도 하나의 행을 반환합니다. 따라서 exists은 항상 true를 반환하고 삭제 작업은 모든 항목을 삭제하려고 시도합니다.

상관 하위 쿼리와 not exists를 사용해보십시오 :

delete 
from table1 t1 
where not exists (
     select 1 
     from table2 t2 
     where t1.compositekey1 = t2.compositekey1 
      and t1.compositekey2 = t2.compositekey2 
      and t1.compositekey3 = t2.compositekey3 
     ); 

당신은 왼쪽을 사용하여이 작업을 수행 할 수 있습니다 조인도 :

delete t1 
from table1 t1 
left join table2 t2 on t1.compositekey1 = t2.compositekey1 
    and t1.compositekey2 = t2.compositekey2 
    and t1.compositekey3 = t2.compositekey3 
where t2.compositekey1 is null; 

을 또한, 나는 당신이 모든 세 개의 열을 확인하려고했던 것으로 나타났습니다 하위 쿼리에서 null입니다. 하나만 선택하면됩니다.

+0

일했다. 고마워. 나는 SQL 책을 통해 갈 것이지만 아직 충분히 멀리 가지 않았다. – DavidBoyd

0

이것은 또한 작동합니다 :

DELETE 
FROM 
    table1 
WHERE 
    EXISTS 
    (
     SELECT 
      * 
     FROM 
      table2 
     WHERE 
      table1.compositekey1 = table2.compositekey1 
     AND table1.compositekey2 = table2.compositekey2 
     AND table1.compositekey3 = table2.compositekey3);