SQL : JOIN & SUBQUERY

Skele·2025년 5월 20일

SQL

목록 보기
5/11
post-thumbnail

1. 조인(JOIN)

조인은 여러 테이블의 데이터를 사용하여 동시에 출력하거나 참조할 때 사용하는 기법이다.

1.1 조인의 종류

조건의 형태에 따른 분류

  1. EQUI JOIN(등가 JOIN)

    • 조인 조건이 동등 조건(=)인 경우
    • 가장 많이 사용되는 조인 방법
    SELECT e.empno, e.ename, d.dname
    FROM emp e, dept d
    WHERE e.deptno = d.deptno;
  2. NON EQUI JOIN(비등가 JOIN)

    • 조인 조건이 동등 조건이 아닌 경우(>, <, BETWEEN 등)
    SELECT e.ename, e.sal, s.grade
    FROM emp e, salgrade s
    WHERE e.sal BETWEEN s.losal AND s.hisal;

조인 결과에 따른 분류

  1. INNER JOIN(내부 조인)

    • 조인 조건에 만족하는 데이터만 출력
    • ORACLE의 기본 조인 방식
  2. OUTER JOIN(외부 조인)

    • 조인 조건에 만족하지 않는 데이터도 출력
    • LEFT/RIGHT/FULL OUTER JOIN으로 구분
    -- ORACLE 구문
    SELECT e.ename, d.dname
    FROM emp e, dept d
    WHERE e.deptno = d.deptno(+);  -- (+) 의 반대편이 기준 : LEFT OUTER JOIN
    
    -- ANSI 표준 구문
    SELECT e.ename, d.dname
    FROM dept d LEFT OUTER JOIN emp e
    ON d.deptno = e.deptno;

기타 조인 유형

  1. SELF JOIN(자체 조인)
    하나의 테이블을 두 번 이상 참조하여 자신과 조인

    SELECT e1.ename AS "사원명", e2.ename AS "관리자명"
    FROM emp e1, emp e2
    WHERE e1.mgr = e2.empno;
  2. CROSS JOIN(교차 조인)
    조인 조건 없이 두 테이블의 모든 조합을 출력(카르티시안 곱)

    SELECT e.ename, d.dname
    FROM emp e CROSS JOIN dept d;

1.2 표준 조인(ANSI 표준)

INNER JOIN

  • 두 테이블 간의 조인 조건을 만족하는 데이터만 반환하는 조인 방식이다.
  • 조인 조건에 일치하지 않는 행은 결과에서 제외된다.
SELECT e.empno, e.ename, d.dname
FROM emp e INNER JOIN dept d
ON e.deptno = d.deptno;

OUTER JOIN

  • 조인 조건을 만족하지 않는 행도 결과에 포함시키는 조인 방식이다.
  • 기준 테이블에 따라 LEFT, RIGHT, FULL OUTER JOIN으로 나뉜다.
-- LEFT OUTER JOIN
SELECT s.name, p.name AS "지도교수"
FROM student s LEFT OUTER JOIN professor p
ON s.profno = p.profno
WHERE s.grade IN (1, 2);

-- RIGHT OUTER JOIN
SELECT s.name, p.name AS "지도교수"
FROM student s RIGHT OUTER JOIN professor p
ON s.profno = p.profno;

-- FULL OUTER JOIN
SELECT s.name, p.name AS "지도교수"
FROM student s FULL OUTER JOIN professor p
ON s.profno = p.profno;

NATURAL JOIN

  • 두 테이블 간에 이름이 같은 모든 컬럼을 자동으로 조인 조건으로 사용하는 조인 방식이다.
  • 동일한 이름의 컬럼이 여러 개 있으면 모든 컬럼이 조인 조건으로 사용된다.
  • ON이나 USING 절을 함께 사용할 수 없다 (문법 에러 발생).
  • 조인 컬럼을 사용할 때 테이블 별칭 또는 테이블명을 사용할 수 없다.
  • 동일한 이름의 컬럼이 없거나 데이터 타입이 다르면 카르티시안 곱이 발생할 수 있어 주의해야 한다.
SELECT e.ename, dname
FROM emp e NATURAL JOIN dept;
  • ONUSING으로 특정 칼럼에 대해 지정하지 못한다.

USING 조건절

  • 조인할 컬럼명이 같을 때, 특정 컬럼만 조인 조건으로 사용하고 싶을 때 활용한다.
  • 괄호는 필수이며, 여러 컬럼을 지정할 수 있다.
SELECT e.ename, dname
FROM emp e JOIN dept
USING (deptno); -- 괄호 필수

2. 서브쿼리(Subquery)

서브쿼리는 하나의 SQL 문 안에 포함된 또 다른 SQL 문을 의미한다. 반드시 괄호로 묶어야 한다.

서브쿼리 사용 가능 위치

  • SELECT 절
  • FROM 절
  • WHERE 절
  • HAVING 절
  • ORDER BY 절
  • DML(INSERT, UPDATE, DELETE) 절

서브쿼리 종류

1. 동작 방식에 따른 서브쿼리

비연관(UN-CORRELATED) 서브쿼리

서브쿼리가 메인쿼리와 독립적으로 실행된다.

SELECT ename, sal
FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

연관(CORRELATED) 서브쿼리

서브쿼리가 메인쿼리의 컬럼을 참조한다.

SELECT e1.ename, e1.sal, e1.deptno
FROM emp e1
WHERE e1.sal > (SELECT AVG(e2.sal) FROM emp e2 WHERE e2.deptno = e1.deptno);

2. 위치에 따른 서브쿼리

스칼라 서브쿼리

SELECT 절에 사용하는 서브쿼리로, 단일 값만 반환해야 한다.

SELECT e.empno, e.ename,
       (SELECT d.dname FROM dept d WHERE d.deptno = e.deptno) AS dname
FROM emp e;

인라인 뷰(Inline View)

FROM 절에 사용하는 서브쿼리로, 테이블처럼 사용된다.

SELECT a.empno, a.ename, a.sal, a.deptno, b.deptno, b.max_sal
FROM emp a,
     (SELECT deptno, MAX(sal) AS max_sal FROM emp GROUP BY deptno) b
WHERE a.deptno = b.deptno AND a.sal = b.max_sal;

3. 반환 개수에 따른 서브쿼리

단일행 서브쿼리

서브쿼리 결과가 1개의 행만 반환한다.

SELECT ename, sal
FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

다중행 서브쿼리

서브쿼리 결과가 여러 행을 반환한다.

SELECT ename, sal
FROM emp
WHERE deptno IN (SELECT deptno FROM dept WHERE loc = 'SEOUL');
다중행 서브쿼리 연산자
  • IN: 목록 중 하나와 일치
  • ANY/SOME: 목록 중 하나라도 조건을 만족
    -- sal > ANY(1000, 2000, 3000)은 sal > 1000과 동일
    SELECT ename, sal FROM emp WHERE sal > ANY(SELECT sal FROM emp WHERE deptno = 10);
  • ALL: 목록의 모든 값과 조건을 만족
    -- sal > ALL(1000, 2000, 3000)은 sal > 3000과 동일
    SELECT ename, sal FROM emp WHERE sal > ALL(SELECT sal FROM emp WHERE deptno = 10);
  • EXISTS: 서브쿼리 결과가 존재하면 참
    SELECT deptno, dname FROM dept d
    WHERE EXISTS (SELECT 1 FROM emp e WHERE e.deptno = d.deptno);

다중컬럼 서브쿼리

서브쿼리 결과가 여러 컬럼을 반환한다.

SELECT ename, sal, deptno
FROM emp
WHERE (deptno, sal) IN (SELECT deptno, MAX(sal) FROM emp GROUP BY deptno);

EXISTS/NOT EXISTS 연산자

  • EXISTS: 서브쿼리 결과가 하나라도 존재하면 메인쿼리 출력
  • NOT EXISTS: 서브쿼리 결과가 없으면 메인쿼리 출력
-- 직원이 있는 부서만 조회
SELECT deptno, dname
FROM dept d
WHERE EXISTS (SELECT 1 FROM emp e WHERE e.deptno = d.deptno);

-- 직원이 없는 부서만 조회
SELECT deptno, dname
FROM dept d
WHERE NOT EXISTS (SELECT 1 FROM emp e WHERE e.deptno = d.deptno);
profile
Tireless And Restless Debugging In Source : TARDIS

0개의 댓글