Dr. E.F.Codd의 RDBMS 논문(1970)을 기초로 한다.
연산자 | SQL | 설명 |
---|---|---|
UNION | UNION UNION ALL | 합집합 (중복 제거) 합집합 (중복 허용) |
INTERSECTION | INTERSECT | 교집합 (공통 요소 추출) |
DIFFERENCE | EXCEPT (Oracle : MINUS) | 차집합 (앞SQL기준으로 - 뒤SQL) |
PRODUCT | CROSS JOIN | 곱집합 (JOIN 조건이 없는 경우 생길 수 있는 모든 데이터의 조합, M*N) (= CARTESIAN PRODUCT) |
DBMS를 구현하기 위해 새롭게 만들어진 연산자
연산자 | SQL | 비고 |
---|---|---|
SELECT | WHERE | |
PROJECT | SELECT | |
(NATURAL) JOIN | NATURAL JOIN INNER JOIN OUTER JOIN USING 조건절 ON 조건절 … | |
DIVIDE | 현재 사용하지 않음 |
n개의 테이블에서 필요 데이터 조회시 필요한 JOIN 조건은 대상(연산 기준) 테이블 개수 하나를 뺀 n-1개 이상이 필요하다. (= 피연산 테이블 개수가 n-1)
SELECT 테이블1.칼럼명, 테이블2.칼럼명, ... -- 유일성 보장을 위해 테이블명을 명시하는 습관을 들이자! FROM 테이블1, 테이블2 WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2; /*ANSI/SQL 표준 방식 (INNER JOIN 명시)*/ SELECT 테이블1.칼럼명, 테이블2.칼럼명, ... -- 유일성 보장을 위해 테이블명을 명시하는 습관을 들이자! FROM 테이블1 INNER JOIN 테이블2 ON 테이블1.칼럼명1 = 테이블2.칼럼명2;
SELECT P.PLAYER_NAME, T.TEAM_ID, STADIUM_NAME FROM PLAYER P, TEAM T, STADIUM S WHERE P.TEAM_ID = T.TEAM_ID AND T.STADIUM_ID = S.STADIUM_ID ORDER BY PLAYER_NAME; SELECT P.PLAYER_NAME, T.TEAM_ID, STADIUM_NAME FROM PLAYER P INNER JOIN TEAM T ON P.TEAM_ID = T.TEAM_ID INNER JOIN STADIUM S ON T.STADIUM_ID = S.STADIUM_ID ORDER BY PLAYER_NAME;
SQL Server의 경우 ON 조건절만 지원, NATURAL JOIN과 USING 조건절은 미지원,
/* WHERE절 JOIN 조건 */ SELECT 테이블.칼럼명, ... FROM 테이블1[ [AS] 별칭], 테이블2[ [AS] 별칭] WHERE 테이블1.칼럼명 = 테이블2.칼럼명; /* FROM 절 JOIN 조건 */ SELECT 테이블.칼럼명, ... FROM 테이블1[ [AS] 별칭] [INNER] JOIN 테이블2[ [AS] 별칭] ON 테이블1.칼럼명 = 테이블2.칼럼명;
SELECT 칼럼명, ... FROM 테이블1 NATURAL [INNER] JOIN 테이블2
SELECT 테이블명.칼럼명, ... FROM 테이블명1[ [AS] 별칭] LEFT [OUTER] JOIN 테이블명2[ [AS] 별칭] ON 테이블명1.칼럼명 = 테이블명2.칼럼명;
SELECT 테이블명.칼럼명, ... FROM 테이블명1[ [AS] 별칭] RIGHT [OUTER] JOIN 테이블명2[ [AS] 별칭] ON 테이블명1.칼럼명 = 테이블명2.칼럼명;
SELECT 테이블명.칼럼명, ... FROM 테이블명1[ [AS] 별칭] FULL [OUTER] JOIN 테이블명2[ [AS] 별칭] ON 테이블명1.칼럼명 = 테이블명2.칼럼명; -- "LEFT/RIGHT JOIN 후 UNION"하면 아래 결과와 같다 -- SELECT 테이블명.칼럼명, ... -- FROM 테이블명1[ [AS] 별칭] LEFT [OUTER] JOIN 테이블명2[ [AS] 별칭] -- ON 테이블명1.칼럼명 = 테이블명2.칼럼명; -- UNION -- SELECT 테이블명.칼럼명, ... -- FROM 테이블명1[ [AS] 별칭] RIGHT [OUTER] JOIN 테이블명2[ [AS] 별칭] -- ON 테이블명1.칼럼명 = 테이블명2.칼럼명;
WHERE, ORDER BY 혼용
SELECT T.TEAM_NAME, T.TEAM_ID, S.STADIUM_NAME FROM TEAM T JOIN STADIUM S ON T.TEAM_ID = S.HOMETEAM_ID ORDER BY TEAM_ID; SELECT T.TEAM_NAME, T.TEAM_ID, S.STADIUM_NAME FROM TEAM T, STADIUM S WHERE T.TEAM_ID = S.HOMETEAM_ID ORDER BY TEAM_ID;
다중 Table JOIN
SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME NEW_DNAME FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO) JOIN DEPT_TEMP T ON E.DEPTNO = T.DEPTNO; SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME NEW_DNAME FROM EMP E, DEPT D, DEPT_TEMP T WHERE (E.DEPTNO = D.DEPTNO) AND (E.DEPTNO = T.DEPTNO);
SELECT 칼럼명, ... FROM 테이블1 [INNER] JOIN 테이블2 USING (칼럼명[, 칼럼명]);
SELECT 테이블명.칼럼명, ... FROM 테이블1[ [AS] 별칭] CROSS JOIN 테이블2[ [AS] 별칭];
집합 연산자
집합 연산자 | 설명 | 비고 |
---|---|---|
UNION | 합집합 (중복 제거) | WHERE 절에 “IN”(같은 칼럼일때만), “OR” 연산자로 변환 가능 |
UNION ALL | 합집합 (중복 허용) | “NOT EXISTS”, “NOT IN” Sub Query로 변환 가능 |
INTERSECT | 교집합 (공통 요소 추출) | “EXISTS”, “IN” Sub Query로 변환 가능 |
EXCEPT (Oracle : MINUS) | 차집합 (앞SQL - (교집합)) |
SELECT ~ [HAVING ~] 집합_연산자 SELECT ~ [HAVING ~] [ORDER BY ~]
SELECT 칼럼명, ... FROM 테이블명, ... WHERE 조건, ... START WITH 조건 CONNECT BY [NOCYCLE] 조건, ... [ORDER SIBLINGS BY 칼럼명, ...]
(Oracle 기준)
SELECT LEVEL, LPAD('~', (LEVEL-1)*4) || EMPNO, --왼쪽 기준 "(LEVEL-1)*4"위치에 '~'삽입하고, EMPNO 칼럼을 덛붙인다. MGR, CONNECT_BY_ISLEAF --Leaf면 1, 아니면 0 FROM EMP START WITH MGR IS NULL CONNECT BY PRIOR EMPNO = MGR; --MGR→EMPNO
SELECT LEVEL, LPAD(EMPNO, LEVEL*4, '~'), --왼쪽 기준 "LEVEL*4"byte 길이로 출력하되 빈 자리는 '~'로 채운다. MGR, CONNECT_BY_ISLEAF --Leaf면 1, 아니면 0 FROM EMP START WITH MGR IS NULL CONNECT BY PRIOR EMPNO = MGR; --MGR→EMPNO
SELECT LEVEL, LPAD(EMPNO, LEVEL*4, '~'), MGR, CONNECT_BY_ISLEAF FROM EMP START WITH EMPNO = '7876' CONNECT BY EMPNO = PRIOR MGR;
(Oracle 기준)
루트 데이터로부터 현재 전개할 데이터까지의 경로 표시
SYS_CONNECT_BY_PATH(칼럼, 경로분리자)
현재 전개할 데이터의 루트 데이터 표시.
CONNECT_BY_ROOT(칼럼)
SELECT 별칭1.칼럼명, 별칭2.칼럼명, ... FROM 테이블명 [AS] 별칭1, 테이블명 [AS] 별칭2 WHERE 별칭1.칼럼명 = 별칭2.칼럼명