| 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을 사용해야한다고 배웠는데 = 도 에러가 나지않고 결과가 나오는 이유가 궁금합니다.
'=' 조건은 해당 서브쿼리의 결과 값이 1개만 나올경우 사용됩니다.
다중 조건이 들어가면 'IN' 으로 사용해야 에러가 나지 않습니다.
예제는 GRADE 3 에 해당되는 결과 ROW 가 1개라서 '=' 와 'IN' 이 동일하게 나오지만, 이것은 예제가 운좋게 에러를 피한 경우이고, 일반적으로는 'IN' 을 사용하는 것이 맞습니다.
예제에서 select sal from emp, salgrade where sal between losal and hisal and grade = 3
을 실행시켰을 경우에 결과가 2개가 나옴에도 불구하고 = 를 사용하니 error가 나오지않았었습니다.
댓글의 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
;
감사합니다!!