연관 서브쿼리(조인이 들어간것) , exists 질문이요~ 0 4 980

by dlwptjdi [SQL Query] [2016.08.25 17:46:37]


안녕하세요~ 쿼리에 대한 이해를 정확하게 하고싶어서 혼자 정리하고 있는데

제가 이해한 부분이 맞는지,, 또 이해가 안가는 부분이 있어서 질문올리게 되었습니다~

 

1. 서브쿼리를 공부하면서 연관서브쿼리에 대한 예를 보았는데요 ,

 select t.team_name, m.player_name 선수명, m.position, m.back_no, m.height, m.team_id
from player m, team t
where m.team_id = t.team_id
and m.height < (select avg(s.height)
                from player s
                where s.team_id=m.team_id
                and s.height is not null
                group by s.team_id)

저의 해석:

처음에는 서브쿼리이 먼저 실행하여 행을 반환하고 -> 메인쿼리(from부터~)를 실행하여 height(선수의 키) 비교한다.

라고 생각했다가 연산자를 보니 비교연산자인 '<' 로 써있기 때문에 따라서 행이 하나만 반환이 되어야 한다고 생각하였구요,

결론 : from 절  두 테이블 (player,team) 조인 -> where 의 조인 조건을 확인하여 테이블 합친다

       -> 두번째 where절 조건의 데이터 제한조건에 있는  m.height 칼럼의 데이터(레코드)를 가져온다.

이때 가져온 행을 참고하여(?) team_id(K01~K15까지 간다고 했을 때) team_id = K01의 값을 갖는 레코드라면,

서브쿼리 안에있는 조인조건에 K01가 전해져 K01에 대한 데이터들로만 이루어져 하나의 그룹(K01)에 대한 평균키를 구하여

하나의 행을 반환한다 -> 비교하여 연산을 마무리한다.

라고 해석하였습니다... 즉, 메인쿼리의 각각의 행들을 바탕으로 서브쿼리의 메인테이블 데이터가 전해지면서 서브쿼리 안에 있는 조인 조건을 보고 테이블이 조건에 맞게 축소(?)가 된다고 할 수 있나요 ??

 

2.

select stadium_id,stadium_name 경기장명
from stadium a
where exists (select 1 from schedule x
               where a.stadium_id=x.stadium_id
               and x.sche_date between '20150101' and '20160502');

exists 서브쿼리 안에 있는 select 1 은 메인쿼리의 stadium_id를 뜻하는 것인가요?

주로 order by 절에서 정수로 매칭하여 사용한다고 배웠는데

서브쿼리에서 select 절에 정수를 매칭하여 메인 테이블의 칼럼을 참조하는 것인지 궁금합니다~!

 

답변해주시면 감사하겠습니다~!

 

by 마농 [2016.08.25 18:02:58]

1. 연관 서브쿼리인지? 아닌지? 는
  - 서브쿼리 안에 메인 컬럼이 조건으로 투입되는지로 판단됩니다.
2. 연관 서브쿼리의 경우 서브에 메인 컬럼을 투입해야 하므로
  - 당연히 메인을 먼저 읽어야 하겠죠.
  - 메인쿼리의 결과를 가지고 건건이 서브쿼리를 수행합니다.
3. 메인의 두테이블 조인 후에 서브쿼리 수행을 한다?
  - 그건 장담 못합니다.
  - m > s > t 순서로 실행될 수도 있습니다.
  - m > t > s 로 수행되기도 하구요
  - t > m > s 로 수행되기도 하지요
  - m 과 s 의 순서만 고정이고 t 의 순서가 어찌 될지는 실행계획을 확인해야 합니다.
4. Exists 서브쿼리의 숫자 1 은?
  - 아무 의미 없는 그냥 숫자 1 입니다.
  - 데이터가 존재 여부만 판단하므로 굳이 특정 컬럼을 조회할 필요는 없습니다.
  - 그렇다고 SELECT 절에 아무것도 안 적으면 에러 나니 그냥 1 을 적습니다.
  - 0 이나 'x' 등도 사용됩니다.


by dlwptjdi [2016.08.25 19:26:06]

 select t.team_name, m.player_name 선수명, m.position, m.back_no, m.height, m.team_id
from player m, team t
where m.team_id = t.team_id
and m.height < (select avg(s.height)
                from player s
                where s.team_id=m.team_id
                and s.height is not null
                group by s.team_id)

완벽한 설명 진짜 감사합니다~!

그런데 ㅠㅠ 하나 더 질문이 있는데요 ~ 저 서브쿼리에서 group by 구문을 빼야 정확하다고 할 수 있나요? 제 생각엔 어차피 group by 할 필요가 없다고 생각해서요 이유는 여러 그룹이 아니라 메인쿼리에서 진행된 각각의 데이터들만 들어가게 되면 굳이 group by 가 필요없을 것 같다는 생각이 들어서요,,


by 마농 [2016.08.26 10:05:40]

네. 맞습니다.

Group By 는 없어도 되는 구문입니다. 굳이 쓸 필요가 없죠. 빼는게 맞습니다.


by dlwptjdi [2016.08.26 10:33:03]

넵~ 쿼리실행시켜보았는데 맞는거같아요~~ 상세하게 답변해주셔서 감사합니다~!!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입