CS/데이터베이스

MySql 중복 행 서브 쿼리문에 join이 사용되는 이유

happy_life 2022. 8. 12. 11:43

[데이터베이스] MySql 중복 행 서브 쿼리문에 join이 사용되는 이유 

 

목차

1. 문제 상황

2. 해결 과정

3. 해결

문제 상황

 

각 행정구역의 평균보다 인구수가 더 큰 정보를 쿼리하라.

 select * from citykorea c1 where population > (select avg(population) from citykorea as c2 where c1.district = c2.district group by district);

 

데이터베이스 첫걸음 서브 쿼리문 공부중 c1.district = c2.district라는 코드는 왜 들어가는지 의문이 생겼다.  sql 쿼리 순서상 where 다음 group by가 오므로 서브 쿼리문의 where을 연산할 당시의 c1.district = c2.district는 같은 것이다.  따라서 같은 것으로 묶는건데 왜 이 코드가 필요한지 모르겠다는 고민을 하였다.

 

 

해결과정

 

1.  구글링을 통해 SQL 실행순서를 찾아보면서 매핑해보았지만, 도무지 이해할 수 없었다.

 

sql 실제 실행 순서 매핑

 

2. join 문법을 다시 확인해보았다.

서브 쿼리문이 join 대신 사용할 수 있다는 것은 알게 되었지만, 해결되지 않았다.

 

3. 서브쿼리문에 대해 다시 검색해보았다.

서브 쿼리문에도 단일 서브 쿼리문, 다중 행 서브 쿼리문 등이 있다는 것을 알게되었고, 이를 바탕으로 DBA 분들께 질문 드렸다.

 

해결

 

유쾌한 스프링방에서 어느 분이 DBA 오픈 톡방을 알려주셔서 질문 드렸고, 문제를 해결할 수 있었다.

 

먼저 구글링을 통해 알게된 SQL 실행 순서가 보장되지 않는다는 것을 답변으로 얻었다. 쿼리에는 실행 계획이라는 것이 존재하고 이에 따라 달라질 수 있다는 것이 현직 DBA분들의 설명이었다. SQL의 각 구문 순서는 일반적으로 구글링 내용이 맞지만, 메인 - 서브 쿼리로 이루어진 구문의 실행순서는 다를 수 있다는 것이었다. 

 

또한 다른 쿼리문을 제시해주시며 비교를 해볼 수 있게 해주셔서 이를 통해 제대로 이해할 수 있었다.

select avg(population) from citykorea group by district;

다른 쿼리 결과

 

위의 코드만을 가지고 쿼리를 하면 원하는 결과를 얻을 수 없었다.

 

원하는 쿼리 결과

 

따라서 이를 해결하기 위해 self join이 필요한데 self join을 위해 c1.district = c2.district가 필요한 것이다. 

또한 단일 쿼리문이 아닌 중복 행 쿼리문이기 때문에 이를 평균에 대한 return 값을 각각 매핑 후 결과를 출력할 수 있게 된다.

 

 

결론적으로, 쿼리는 상황에 따라 다르고, 서브 쿼리문에서 self join을 통해 값을 도출해야 하는 경우도 있다는 것이다.