[MySQL] UPDATE문에서 자기 테이블 서브쿼리 이용하기



member라는 테이블에 정보들이 나와 있다. 이 테이블에서 POOH라는 member_id의 member_name을 git의 member_name으로 바꾸려고 한다. 그래서 쿼리를 이용해 해당 결과값을 반환하도록 한 후 이 값으로 update해주도록 쿼리를 짰다.


하지만, 에러가 떴다. 이 에러를 해석하면, MySQL은 UPDATE나 DELETE시 자기 자신 테이블의 데이터를 바로 사용하지 못한다는 뜻이다. 즉, member 테이블을 update하는데 select member_name from member~ 이렇게 member 테이블(자기 자신 테이블)의 데이터를 바로 사용하지 못한다는 것이다. 그러면 자기 테이블의 데이터는 사용하면서 자기 테이블에서 참조해오지 않게 하면 된다. 그 때 사용하는 것이 서브쿼리이다.



  • 서브쿼리란?

서브쿼리란 하나의 SQL문 안에 포함되어 있는 또 다른 SQL문을 말하는데, 반드시 괄호로 묶어줘서 써야 하고 해당 조건에 근거한 값들을 검색하는 select문장을 작성할 때 유용하다.

서브쿼리만 따로 한 번 작성을 해보자.

하지만 또 에러가 뜬다. 이 오류도 해석해보면 파생된 테이블(서브쿼리)은 반드시 별명(이름)을 가져야 한다는 뜻이다. 즉, 이름 같은 것을 통해 구분을 해주려고 하는 것이다. 따라서, 이름을 지어주면 해결된다. 여기서 파생된 테이블은 서브쿼리를 의미하는데, 서브쿼리를 실행해보면 해당 테이블에 대한 결과값이기 때문에 파생된 테이블이라고 하는 것이다.


나는 a라고 이름을 지었으나 이름은 지어주고 싶은대로 해주면 되고, as를 써서 해줄 수도 있고 그냥 이름만 써서 해줄 수도 있다. 둘 중 아무 방법이나 선택하면 된다.


이를 조금 더 구체적으로 해석해보면, ‘as a’ 부분은 단지 서브쿼리의 이름이고 잘 보면, select * from member;처럼 우리가 일반적으로 보는 select * from (테이블)의 구조인데, (테이블) 자리에 서브쿼리에 대한 결과값 즉, 파생된 테이블이 반환되기 때문에 테이블을 조회해주는 쿼리와 같은 구조임을 알 수 있다. 그리고 파생된 테이블에서 select한 것이기 때문에 자기 자신 테이블(member)를 참조하지 않아 아까와 같은 오류가 뜨지 않게 된다.그래서 실제로 비교해보면, 결과값이 같다.


참고 : 첫번째 쿼리를 보면 서브쿼리의 반환값이 member_name이기 때문에 *를 쓰지 않고 member_name을 써줘도 똑같은 값이 나온다.

그럼 이를 이용해 다시 POOH의 member_name을 git의 member_name으로 바꿔보자.


서브쿼리의 이름도 지정해줬고, 파생된 테이블에서 select한 값으로 update한 것이기 때문에 자기 자신 테이블(member)을 참조하지도 않아 아까와 같은 오류들이 뜨지 않고 잘 실행된다.

이제 member 테이블을 다시 확인해보자.


잘 바뀌었음을 확인할 수 있다. 이 서브쿼리는 UPDATE문에서만 해당되는 얘기는 아니고 서브쿼리를 사용할 수 있는 상황이면 다 똑같이 통용되는 얘기다.


이전글: [PHP 챗봇] 3. 웹 크롤링 다음글: [MySQL] INSERT문 여러 개 한 번에 넣기