[Database] 서브 쿼리
서브쿼리란?
기존까지 진행했던 쿼리는 1개였다. 하지만 쿼리 내에 쿼리를 집어넣을 수 있는 경우가 존재하는데 이를 서브 쿼리라고 한다.
서브 쿼리는 메인 쿼리 안에 또 다른 SELECT문장을 말한다.
스칼라 서브쿼리
스칼라 서브쿼리는 메인 쿼리의 SELECT 절에서 컬럼이나 표현식처럼 사용되는 쿼리를 의미합니다.
따라서 해당 쿼리의 결과가 여러개의 컬럼을 반환하거나 그러면 안됩니다.
SELECT a.emp_id,
a.emp_name,
a.gender,
a.age,
a.dept_id,
(SELECT b.dept_name
FROM dept_master b
WHERE a.dept_id = b.dept_id) dept_name
FROM emp_master a
서브쿼리는 dept_name이라는 컬럼을 추출한다. 이때 a.dept_id를 이용해서 dept_master 테이블에서 dept_name을 추출하게 된다.
위의 예시를 JOIN으로 만들면 다음과 같습니다.
SELECT a.emp_id,
a.emp_name,
a.gender,
a.age,
a.dept_id,
b.dept_name
FROM emp_master a,
dept_master b
WHERE a.dept_id = b.dept_id;
서브 쿼리 vs JOIN은 아래 글에 잘 나와있습니다.
https://kimsyoung.tistory.com/entry/SUBQUERY-와-JOIN-의-차이-上
SUBQUERY 와 JOIN 의 차이 (上)
SQL 쿼리문을 작성하면서 마주할 고민 중 하나는 바로 서브 쿼리와 조인 중 어떤 문법을 사용하는 것이 좋을지 판단하는 것입니다. 상황에 따라 조인을 사용하는 것이 훨씬 좋을 때도 있고, 반면
kimsyoung.tistory.com
https://kimsyoung.tistory.com/entry/SUBQUERY-와-JOIN-의-차이-下
SUBQUERY 와 JOIN 의 차이 (下)
이전 편 SUBQUERY 와 JOIN 의 차이 (上) 에서는 서브 쿼리를 조인으로 대체하여 작성할 수 있는 경우를 살펴보았습니다. 서브 쿼리를 조인으로 굳이 재작성하는 가장 큰 이유는 쿼리의 수행력 때문입
kimsyoung.tistory.com
인라인 뷰
FROM절에서 서브쿼리 자체가 하나의 테이블 처럼 사용되는 경우를 인라인 뷰라고 합니다.
예시 코드
Q)부서를 기준으로 각 부서에 속한 사원의 사원번호, 이름, 주소를 조회하는 쿼리를 만들어보세요.
SELECT
a.dept_id,
a.dept_name,
k.emp_id,
k.emp_name,
k.address
FROM dept_master a
,(SELECT
b.emp_id,
b.emp_name,
c.city || c.gu || c.address_name AS address,
b.dept_id
FROM
emp_master b,
address_master c,
WHERE b.address_id = c.address_id
)k
WHERE a.use_yn = 'Y'
AND a.dept_id = k.dept_id
ORDER BY 1, 3
여기서 주의해야할 점은 인라인뷰에서 만들어진 테이블 같은 경우 결국에는 테이블이고 이들을 동시에 보여주기 위해서는 JOIN을 해줘야 한다는 것이다.
중첩 서브쿼리
WHERE 절에서 사용하는 서브쿼리이다. 따라서 이들은 SELECT쿼리 결과가 조건절의 일부로 사용된다는 뜻이다.
SELECT *
FROM dept_master a
WHERE a.dept_id = (
SELECT b.dept_id
FROM emp_master b
WHERE b.emp_name = '세종대왕'
);
해당 조건문은 emp_master 테이블에서 이름이 세종대왕인 사람의 주소관련 정보를 dept_master 테이블에서 가져오는 SQL문이다.
WHERE 절에서 동등 연산자를 사용했기 때문에 서브 쿼리의 결과는 1개 또는 0개가 나와야한다.
만약 동등연산자가 아니고 서브쿼리의 결과가 여러개가 나온다면 =가 아니라 IN을 써야한다.
SELECT *
FROM emp_master a
WHERE (a.gender, a.age) IN (
SELECT b.gender, b.age
FROM emp_master b, address_master c
WHERE b.address_id = c.address_id
AND c.gu IN ('중구', '서대문구')
);
위의 쿼리는 중구와 서대문구에 속한 사원의 성별과 나이를 반환하는 SQL쿼리문이다.
위의 메인 쿼리 내에 서브 쿼리의 질의 결과는 다음과 같다.
근데 이상한 점이 있다 서브 쿼리의 결과는 3개인데 위의 메인 쿼리에 대한 결과는 4개이다.
emp_master db를 살펴보면 홍길동과 세종대왕이 둘 다 성별이 남성이고 나이가 45세 이기 때문이다.
이처럼 중첩 서브쿼리에서는 다중행, 다중 컬럼을 반활 할 수 있다.
본 글은 '누구나 쉽게 SQL'이라는 책을 읽고 정리한 내용입니다.
http://www.yes24.com/Product/Goods/74311553
누구나 쉽게 SQL - YES24
설명은 쉽게 + 기본기는 튼실하게두 마리 토끼를 다 잡은 SQL 입문서!『누구나 쉽게 SQL』 은 데이터베이스의 기초부터 SQL 사용법과 동작 원리까지 반드시 알아야 하는 핵심만 담은 도서이다. 핵
www.yes24.com
더 많은 내용을 알고 싶은 분은 위의 책을 보시길 바랍니다.
긴 글 읽어주셔서 감사합니다.
틀린 부분이 있으면 댓글을 달아주시면 감사하겠습니다.
📧 : may3210@g.skku.edu