MySQL에서는 DELETE 대상 테이블을 서브쿼리에서 직접 참조할 수 없습니다. 이 경우 "You can't specify target table for update in FROM clause"라는 오류가 발생합니다. 이를 해결하려면 서브쿼리 결과를 파생 테이블(Derived Table)로 한 번 더 감싸야 합니다. 아래 예제를 통해 단계별로 살펴보겠습니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다.
mysql> create table DemoTable1947
(
Id int,
Name varchar(20)
);
Query OK, 0 rows affected (0.00 sec)2. 샘플 데이터 삽입하기
INSERT 명령을 사용하여 테이블에 레코드를 추가합니다.
mysql> insert into DemoTable1947 values(101,'Chris'); Query OK, 1 row affected (0.00 sec) mysql> insert into DemoTable1947 values(102,'David'); Query OK, 1 row affected (0.00 sec) mysql> insert into DemoTable1947 values(103,'Mike'); Query OK, 1 row affected (0.00 sec) mysql> insert into DemoTable1947 values(104,'Bob'); Query OK, 1 row affected (0.00 sec) mysql> insert into DemoTable1947 values(105,'Sam'); Query OK, 1 row affected (0.00 sec)
3. 전체 레코드 조회하기
SELECT 문으로 테이블의 모든 레코드를 확인합니다.
mysql> select * from DemoTable1947;
위 쿼리는 다음과 같은 결과를 출력합니다.
+------+-------+ | Id | Name | +------+-------+ | 101 | Chris | | 102 | David | | 103 | Mike | | 104 | Bob | | 105 | Sam | +------+-------+ 5 rows in set (0.00 sec)
4. 서브쿼리를 활용한 DELETE 실행하기
아래는 서브쿼리로 SELECT한 결과를 기반으로 DELETE를 수행하는 쿼리입니다. 핵심은 내부 서브쿼리를 as t 별칭을 가진 파생 테이블로 감싸는 것입니다.
mysql> delete from DemoTable1947 where Id
IN(select * from (select Id from DemoTable1947 order by Id limit 3)as t);
Query OK, 3 rows affected (0.00 sec)이 쿼리는 다음과 같은 방식으로 동작합니다.
- 내부 서브쿼리가
order by Id limit 3를 통해 Id 기준 오름차순으로 상위 3개 행(101, 102, 103)을 선택합니다. - 이 결과가 별칭
t를 가진 파생 테이블이 되어, DELETE 대상 테이블과의 직접 참조 충돌을 피할 수 있습니다. - 외부 DELETE 문은 해당 Id 값들과 일치하는 행을 삭제합니다.
5. 삭제 결과 확인하기
테이블의 레코드를 다시 조회하여 삭제가 정상적으로 적용되었는지 확인합니다.
mysql> select * from DemoTable1947;
실행 결과는 다음과 같습니다.
+------+------+ | Id | Name | +------+------+ | 104 | Bob | | 105 | Sam | +------+------+ 2 rows in set (0.00 sec)
Id가 101, 102, 103인 세 개의 레코드가 성공적으로 삭제되고, 나머지 두 개의 레코드만 남은 것을 확인할 수 있습니다. 이처럼 파생 테이블로 서브쿼리를 감싸는 패턴을 사용하면 MySQL에서 자기 참조 조건의 DELETE 작업을 안전하게 수행할 수 있습니다.