서브쿼리 관련 질문 4

by 레모온 [SQL Developer] [2022.04.27 17:27:43]


  grade losal hisal
  1 700 1200
  2 1201 1400
  3 1401 2000
  4 2001 3000
  5 3001 9999

▲salgrade

위 테이블에서 grade 3에 해당하는 sal을 가진 사람을 emp라는 테이블에서 뽑는다 했을때

select sal from emp

where sal in (select sal from salgrade where sal between losal and hisal and grade = 3);

-----------------------------------------------

select sal from emp

where sal = (select sal from salgrade where sal between losal and hisal and grade = 3);

 

이 두개 다 결과가 정상적으로 나옵니다.

원래는 다중행 서브쿼리는 in을 사용해야한다고 배웠는데 = 도 에러가 나지않고 결과가 나오는 이유가 궁금합니다.

 

by 우주민 [2022.04.27 17:36:24]

'=' 조건은 해당 서브쿼리의 결과 값이 1개만 나올경우 사용됩니다.

다중 조건이 들어가면 'IN' 으로 사용해야 에러가 나지 않습니다.

예제는 GRADE 3 에 해당되는 결과 ROW 가 1개라서 '=' 와 'IN' 이 동일하게 나오지만, 이것은 예제가 운좋게 에러를 피한 경우이고, 일반적으로는 'IN' 을 사용하는 것이 맞습니다.


by 레모온 [2022.04.27 17:43:16]

예제에서 select sal from emp, salgrade where sal between losal and hisal and grade = 3

을 실행시켰을 경우에 결과가 2개가 나옴에도 불구하고 = 를 사용하니 error가 나오지않았었습니다.


by 마농 [2022.04.27 18:06:45]

댓글의 2행이 나온 쿼리와 서브쿼리는 다른 쿼리입니다. FROM 절이 다름
사용하신 서브쿼리의 FROM 절엔 emp 가 없죠.
서브쿼리 자체만 단독으로 수행하면 에러 날 것입니다.
salgrade 에 없는 sal 항목을 사용하기 때문입니다.
그럼에도 불구하고 서브쿼리로 사용시에 에러가 안나는 이유는
서브쿼리에서 사용하는 sal 은 메인쿼리의 sal 을 이용하기 때문입니다.
이처럼 서브쿼리에서 메인의 항목을 이용하는 서브쿼리를 상관서브쿼리라고 합니다.
상관서브쿼리를 사용한다면 위처럼 = 사용도 가능하긴 하지만 Exists 를 주로 사용합니다.
또한 댓글의 2건이 나온 쿼리처럼 애초에 서브쿼리보다는 조인이 마땅합니다.

SELECT *
  FROM emp a
 WHERE EXISTS (SELECT 1
                 FROM salgrade b
                WHERE a.sal BETWEEN b.losal AND b.hisal
                  AND b.grade = 3
               )
;

SELECT *
  FROM emp a
     , salgrade b
 WHERE a.sal BETWEEN b.losal AND b.hisal
   AND b.grade = 3
;

 


by 레모온 [2022.04.27 18:43:44]

감사합니다!!

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