본문으로 건너뛰기

표준 조인

SQLD 목차SQL 기본레슨 23 / 35

목차

표준 조인(STANDARD JOIN)은 FROM 절에 조인 방식과 조건을 함께 씁니다. NATURAL·USING은 이름이 같은 열로, ON은 직접 쓴 조건으로 잇고, CROSS는 조건 없이 모든 행끼리 짝짓습니다.

조인의 INNER JOIN … ON처럼 FROM 절에 JOIN 키워드를 쓰는 문법은 ANSI/ISO SQL 표준입니다. 조인 조건은 ON에, 행을 거르는 조건은 WHERE에 나눠 쓸 수 있습니다. 내부 조인은 어디에 두어도 같지만, 외부 조인에서는 같은 조건이라도 ON에 두느냐 WHERE에 두느냐에 따라 결과가 달라집니다.

7단계 중 1단계. NATURAL JOIN은 두 테이블에서 이름이 같은 열을 모두 찾아, 그 값이 같은 행끼리 잇습니다.

1NATURAL JOIN과 USING

EMP와 DEPT는 이름이 같은 열이 DEPTNO 하나라, NATURAL JOIN과 USING (DEPTNO)가 같은 5행을 냅니다. 다만 NATURAL JOIN은 이름만 같고 뜻이 다른 열이 있어도 그 열까지 같아야 잇습니다. 이을 열을 정해 두려면 USING을 씁니다. 두 방식에서 이은 열은 두 테이블의 열이 하나로 합쳐져, 그 열 앞에는 E. 같은 테이블 별칭도 EMP. 같은 테이블 이름도 붙일 수 없습니다(Oracle은 NATURAL에서 ORA-25155, USING에서 ORA-25154). DEPTNO AS D처럼 결과 열에 붙이는 별칭은 됩니다.

구분NATURALUSINGON
이을 열이름이 같은 열 모두고른 열조건으로 정함
그 열 앞의 테이블 별칭(E.)못 붙임못 붙임붙여서 가름
SELECT *의 그 열맨 앞에 하나맨 앞에 하나테이블마다 하나
SQL Server없음없음있음

2ON과 CROSS JOIN

ON으로 이으면 두 테이블의 DEPTNO가 따로 남으므로, SELECT에서는 D.DEPTNO처럼 어느 쪽인지 밝혀야 합니다. 열 이름이 다르거나 =가 아닌 조건으로 이을 때도 ON을 씁니다.

CROSS JOIN의 결과는 카티션 곱으로, 쉼표로 늘어놓고 조인 조건을 빼먹은 것과 같습니다. JOIN만 쓰고 ON·USING을 빠뜨린다고 CROSS JOIN이 되지는 않습니다. Oracle은 ORA-02000 오류를 냅니다.

3외부 조인에서 ON과 WHERE

LEFT OUTER JOIN의 ON에 더한 D.LOC = '서울'은 짝 후보를 서울 부서(10·40)로 좁힐 뿐이라, EMP의 행은 하나도 없어지지 않습니다. 같은 조건을 WHERE에 두면 조인을 마친 6행을 거릅니다. 판교·부산 줄과 외부 조인으로 남긴 정하늘 줄(LOC NULL)이 빠집니다. Oracle (+)는 NULL로 채워지는 쪽의 상수 조건에도 붙여야 ON에 둔 것과 같고, 빠뜨리면 오류 없이 WHERE에 둔 것과 같아집니다.

조건쓰이는 때이 예 행 수
ON에 둔 D.LOC = '서울'짝을 고를 때6
WHERE에 둔 D.LOC = '서울'조인을 마친 뒤1

예제

NATURAL JOIN의 SELECT *입니다. 열 차례를 보려고 한 행만 골랐습니다.

SELECT *
FROM EMP
  NATURAL JOIN DEPT
WHERE EMPNO = 1001;
DEPTNOEMPNOENAMESALMGRDNAMELOC
101001김민준520NULL기획서울

USING으로 고른 쿼리입니다. 결과는 5행이고, E.DEPTNO로 쓰면 ORA-25154 오류입니다.

SELECT E.EMPNO,
  E.ENAME,
  DEPTNO,
  D.DNAME
FROM EMP E
  JOIN DEPT D
  USING (DEPTNO)
ORDER BY E.EMPNO;

ON으로 이으면 DEPTNO가 두 번 나옵니다.

SELECT *
FROM EMP E
  JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
WHERE E.EMPNO = 1001;
EMPNOENAMESALDEPTNOMGRDEPTNODNAMELOC
1001김민준52010NULL10기획서울

CROSS JOIN의 행 수입니다.

SELECT COUNT(*) AS CNT
FROM EMP
  CROSS JOIN DEPT;
CNT
24

외부 조인의 ON에 조건을 두면 김민준 말고는 DEPT 쪽이 NULL인 6행입니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME,
  D.LOC
FROM EMP E
  LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
  AND D.LOC = '서울'
ORDER BY E.EMPNO;

같은 조건을 WHERE에 두면 김민준 1행만 남습니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME,
  D.LOC
FROM EMP E
  LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
WHERE D.LOC = '서울'
ORDER BY E.EMPNO;

Oracle (+)로 쓰면 ON에 둔 것과 같은 6행입니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME,
  D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO(+)
  AND D.LOC(+) = '서울'
ORDER BY E.EMPNO;

시험 포인트

  • NATURAL JOIN은 이름이 같은 열을 모두 조인 조건으로 씁니다. 뜻이 다른 열도 이름이 같으면 같아야 이어집니다.
  • NATURAL JOIN과 USING에 쓰인 열 앞에는 테이블 이름이나 별칭을 붙일 수 없고, SELECT *에서 맨 앞에 한 번 나옵니다. SQL Server에는 둘 다 없습니다.
  • CROSS JOIN은 카티션 곱입니다. ON·USING 없는 JOIN은 오류입니다(ORA-02000).
  • 외부 조인에서 ON의 조건은 짝을 고를 뿐 기준 쪽 행을 없애지 않고, WHERE의 조건은 조인이 끝난 결과에서 행을 지웁니다. Oracle (+)는 NULL로 채워지는 쪽의 조건 모두에 붙입니다.

확인 문제

1. Oracle에서 오류가 나는 쿼리를 고르세요.

  • ① SELECT DEPTNO FROM EMP NATURAL JOIN DEPT;
  • ② SELECT E.DEPTNO FROM EMP E NATURAL JOIN DEPT D;
  • ③ SELECT E.ENAME FROM EMP E JOIN DEPT D USING (DEPTNO);
  • ④ SELECT D.DEPTNO FROM EMP E JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
정답

②입니다. NATURAL JOIN에 쓰인 DEPTNO 앞에 테이블 별칭 E.를 붙여서 ORA-25155 오류가 납니다. ③의 ENAME은 조인에 쓰이지 않아 테이블 별칭을 붙여도 되고, ④는 ON으로 이어 오히려 D.DEPTNO처럼 밝혀 써야 합니다.

2. 다음 두 쿼리는 각각 몇 행을 돌려줄까요?

SELECT E.EMPNO,
  E.ENAME,
  D.DNAME
FROM EMP E
  LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
  AND D.DNAME = '개발'
ORDER BY E.EMPNO;
SELECT E.EMPNO,
  E.ENAME,
  D.DNAME
FROM EMP E
  LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
WHERE D.DNAME = '개발'
ORDER BY E.EMPNO;
정답

첫째는 6행, 둘째는 3행입니다.

첫째 쿼리는 ON에서 '개발' 부서만 짝 후보로 삼고, EMP 6행을 모두 남깁니다. 김민준·최유나·정하늘의 DNAME은 NULL입니다. 둘째 쿼리는 조인한 뒤 WHERE가 DNAME이 '개발'인 행만 남깁니다.

EMPNOENAMEDNAME
1002이서연개발
1003박지호개발
1006강도윤개발

3. 다음 Oracle 쿼리는 몇 행을 돌려줄까요? EMP 6행이 모두 나오게 하려면 어디를 고치면 될까요?

SELECT E.EMPNO,
  E.ENAME,
  D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO(+)
  AND D.LOC = '판교'
ORDER BY E.EMPNO;
정답

3행입니다.

EMPNOENAMELOC
1002이서연판교
1003박지호판교
1006강도윤판교

D.LOC = '판교'에 (+)가 없어서, 짝이 없어 LOC가 NULL로 채워진 행이 이 조건에서 빠집니다. D.LOC(+) = '판교'로 고치면 EMP 6행이 모두 나옵니다. 표준 조인으로는 조건을 ON에 둡니다.

LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
  AND D.LOC = '판교'

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

SQLD 목차로