2015-11-03
일전에 사용했던 testbl에 임의의 데이터를 집어넣은 뒤에 삭제를 해보려고 한다.

MariaDB [test]> select * from `testbl`;
+-----+------+-------+-------+
| idx | int1 | int2  | char1 |
+-----+------+-------+-------+
|   1 |  123 | 00123 | 123   |
|   2 |    1 | 01234 | 123   |
|   3 |    2 | 01234 | 123   |
|   4 |    3 | 01234 | 123   |
|   5 |    1 | 01234 | 123   |
|   6 |    2 | 01234 | 123   |
+-----+------+-------+-------+
6 rows in set (0.00 sec)

자 그럼 int1컬럼의 값이 1인 것만 삭제를 해보자.

MariaDB [test]> delete from `testbl` where `idx` in (select `idx` from `testbl` where `int1` = 1);
ERROR 1093 (HY000): Table 'testbl' is specified twice, both as a target for 'DELETE' and as a separate source for data

사실 위와 같이 간단한 쿼리는, 굳이 idx를 in으로 할 필요 없이, 그냥 where `int1` = 1 로만으로 끝낼 수 있다.
하지만, 테이블의 구조에 따라서나 join을 사용해야 할때는 위처럼 서브쿼리로 삭제구문을 작성해야 할 일도 생긴다.
그리고 이럴땐 위와 같이 사용시엔 에러가 뜬다..

에러 내용을 간단히 설명하면, 해당 테이블에서의 조회된 값을 바탕으로 해당 테이블을 조작하면 안된다는 것이다.

하지만 위 에러는 아래와 같이 피해갈 수 있다.

MariaDB [test]> delete from `testbl` where `idx` in (select * from (select `idx` from `testbl` where `int1` = 1));
ERROR 1248 (42000): Every derived table must have its own alias

mysql도 마찬가지지만 mariaDB는 from뒤에 오는 값을 select로 뽑아낼 경우 별칭(alias)값을 주지 않으면 에러가 뜬다.

MariaDB [test]> delete from `testbl` where `idx` in (select * from (select `idx` from `testbl` where `int1` = 1) a);
Query OK, 2 rows affected (0.00 sec)

자 이제 별칭도 다 주었더니 제대로 삭제가 되었다.

MariaDB [test]> select * from `testbl`;
+-----+------+-------+-------+
| idx | int1 | int2  | char1 |
+-----+------+-------+-------+
|   1 |  123 | 00123 | 123   |
|   3 |    2 | 01234 | 123   |
|   4 |    3 | 01234 | 123   |
|   6 |    2 | 01234 | 123   |
+-----+------+-------+-------+
4 rows in set (0.02 sec)