RDBMS는 중복을 최소화하는 형태의 데이터 베이스이다.
다른 테이블과 연결해준다.
****************WHERE + JOIN SELECT SQL 의 모든것 ***********
JOIN : 다른 테이블과 연결하여 데이터를 확장하는 문법
. COLUMN 을 확장한다.
** 행을 확장 -> 집합연산자 ( Union, Intersect minus )
-> 다음 번 설명할것
JOIN 문법 구분
1. ANSI - SQL
: RDBMS 에서 사용하는 SQL 표준 문법
(표준을 잘 지킨 모든RDMBS-MYSQL, MSSQL, POSTGRESQL...에서 실행가능 )
2. ORACL E - SQL
: ORACLE 사 만의 고유 문법
ANSI SQL 에 있는
Natural join : join 하고자 하는 테이블의 컬럼명이 같은 컬럼끼리 연결
컬럼의 값이 같은 행들끼리 연결
ANSI - SQL
SELECT 컬럼
FROM 테이블명 Natural join 테이블명;
SELECT emp.empno , deptno, dept.dname
FROM emp NATURAL JOIN dept ;
그냥
컬럼명이 한쪽 테이블에만 존재할 경우 테이블 한정자를 붙이지 않아도 상관없다.
SELECT empno , deptno, dname
FROM emp Natural JOIN dept;
-> 테이블간의 column이 같아야되는 제약사항
조인 컬럼에 테이블 한정자를 붙이면 natural join 에서는 에러로 취급
NATURAL JOIN 에서는 동일한 컬럼에다가 emp.deptno 나 dept.deptno 같이 한정자를
조인하는 컬럼 앞에다가 붙이면 안된다.
NATURAL join 을 oracle 문법으로 ( 동일한 행인 deptno 는 앞에 나오네 항상 )
1. FROM 절에 조인할 테이블을 나열( , ) 한다.
2. WHERE 절에 테이블 조인 조건을 기술하다.
요렇게 써줘야함
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno;
컬럼이 여러개의 테이블에 동시에 존재하는 상황에서 테이블 한정자를 붙이지 않아서
오라클 입장에서는 해당 컬럼이 어떤 테이블의 컬럼인지 알수가 없을 때 오류
: ( 근데 NATURAL JOIN 에서 SELECT 에 공통된 deptno 앞에 한정자를 붙일 수 없음
SELECT *
FROM emp, dept
WHERE deptno = deptno ;
-----> deptno 가 어디에서 오는 deptno인지 알아야함
emp 테이블에 있는 부서번호가 dept 테이블에 있는 부서 번호랑 같을때
인라인뷰 별칭처럼 테이블 별칭을 부여하는 게 가능하다.
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno ;
-->
SELECT *
FROM emp e, dept d
WHERE e.deptno = d.deptno ;
ANSI - SQL : JOIN WITH USING
조인하려는 테이블간 같은 이름의 컬럼이 2개 이상일 때 하나의 컬럼으로만 조인을 하고
싶을 때 사용
SELECT *
FROM emp JOIN dept USING (deptno) ;
ORACLE 문법에서
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno ;
ANSI - SQL : JOIN WITH ON - 조인 조건을 개발자가 직접 기술
NATURAL JOIN , JOIN WITH USING 절을 JOIN WITH ON 절을 통해 표현 가능
SELECT *
FROM emp JOIN dept on ( emp.deptno = dept.deptno ) ;
ORACLE
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND deptno IN ( 20, 30 )
----> 오류
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND emp.deptno IN ( 20, 30 ) ;
--> 이것처럼 deptno 가 emp인지 dept 인지 구분을 해줘야 오류가 나지 않음
논리적인 형태로 구분을 함
논리적인 형태에 따른 조인 구분
1. SELF JOIN : 조인하는 테이블이 서로 같은 경우 ( 예를 들어서 emp에는 매니저의
숫자가 나와있는게 emp 자신의 테이블
SELECT e.empno , e.ename, e.mgr , m.ename
FROM emp e JOIN emp m on ( e.mgr = m.empno )
여기서 e와 m은 똑같은 emp 라는 테이블에서 그냥 임의로 e . m 으로 나눠서
비교하면서 mgr과 ename을 연결해준것
ORACLE
SELECT e.empno, e.ename , e.mgr, m.ename
FROM emp e, emp m
WHERE e.mgr = m.empno ;
emp 테이블 :
emp 테이블에서 mgr 메니저가 empno 에서 찾아볼 수 있다.
그래서 이 mgr을 empno 로 연결해주려고 한다. self join
SELECT e.empno, e.ename , e.mgr, m.ename
FROM emp e JOIN emp m on ( e.mgr = m.empno )
---> 오라클에서
SELECT e.empno, e.ename, e.mgr, m.ename
FROM emp e, emp m
WHERE e.mgr = m.empno ;
앞에사진은 14번이 있는데 뒤에 오라클에서 표현한 것은 14번이 없어
king 의 경우 매니저 컬럼의 값이 null이기 때문에 e.mgr = m.empno
조건을 충족시키지 못함
그래서 조인 실패해서 14건중 13건의 데이터만 조회가 된다.
2. nonqui join 조인 조건이 = 이 아닌 조인
SELECT *
FROM emp, dept
WHERE emp.empno = 7369
AND emp.deptno != dept.deptno ;
emp :
SELECT *
FROM emp, dept
WHERE emp.empno = 7369
AND emp.deptno != dept.deptno ;
:
SAL 을 이용해서 등급 구하기
SELECT *
FROM salgrade;
empno, ename sal , 등급
SELECT empno, ename, sal, grade
FROM emp, salgrade
WHERE emp.sal >= losal
AND sal <= hisal;
:
SQL 처럼 하면
SELECT empno, ename, sal, grade
FROM emp, salgrade
WHERE sal BETWEEN losal AND hisal ;
-> 위에랑 동일
위에 sql을 ansi - sql로 변경
SELECT empno, ename, sal, grade
FROM emp JOIN salgrade ON ( sal >= losal and sal <= hisal );
내 정리
1. NATURAL JOIN 과 ORACLE
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno
와
SELECT *
FROM emp NATURAL JOIN dept
동일
만약
SELECT *
FROM emp, dept
이렇게 쓰면 deptno 가 동일한 절이 생성되지 않기때문에 더 길어짐
2. JOIN WITH USING 과 ORACLE
JOIN WITH USING 에서
SELECT *
FROM emp JOIN dept USING (deptno) ;
이거는 emp 테이블이랑 dept 테이블을 같이 합칠건데 deptno 가 동일한 애들을 바탕으로
할거다.
그러면 deptno 는 조인한거니까 맨 앞으로 출력이 되고 deptno 가 emp에서 20이면 dept
에서 emp 가 20 인 사람은 research 10 인 사람은 accounting 30인 사람은 sales 라고
옆에 붙어서 나오게 된다.
SELECT *
FROM dept
SELECT *
FROM emp
------JOIN WITH USING 으로 쓴것
SELECT *
FROM emp JOIN dept USING (deptno) ;
-- using 뒤에 deptno 에 괄호로 묶어 주어야 한다.
얘는
-----------위에 있던
SELECT *
FROM emp JOIN dept USING (deptno) ;
-----얘를 ORACLE에서 쓰면
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno ;
얘는 앞에 deptno 가 나오지 않고 중간에 deptno 가 동일한 곳을 같이 두개행으로 써준다.
두개를 그냥 붙여준 것 같이
중요한 것 :
SELECT *
FROM emp a JOIN emp b
ON ( m.mgr = s.empno ) ;
여기서는 열이 13열만 나오는데
자식인 emp 배열에서 mgr이 없었던 king 이라는 애는 둘이 join 을 했을때 사라지게
된다. 즉 join을 한 뒤 자식배열이 늘 원래의 데이터테이블처럼 뽑아져 나오는 것은 아니다.
원래 emp 테이블
salgrade와 emp 테이블을 조인한 테이블
emp 테이블과 salgrade 테이블이 합쳐졌는데
emp 테이블에 있는 ename을 보면 king 이 사라져 있음
문제풀기
데이터 결합 ( 실습 join 0 )
emp, dept 테이블을 이용하기
푸는 과정
1. 우선 각 COLUMN 이 어디서 오는지를 보기
SELECT *
FROM emp
얘랑
SELECT *
FROM dept
얘를 비교해서 보기
emp 에서는 empno , ename 를 가져오고
dept 에서는 dname을 가져오고
공통은 deptno 이다.
답
SQL 로
SELECT empno, ename, emp.deptno, dname
FROM emp, dept
WHERE emp.deptno = dept.deptno
ORDER BY emp.deptno
natural join 으로
SELECT empno, ename, deptno, dname
FROM emp NATURAL JOIN dept
ORDER BY deptno
* NATURAL JOIN 을 할때는 공통되는 COLUMN에는 한정자를 붙이면 안된다
나머지는 COLUMN에 한정자를 붙이지 않은 이유는 각각 한개만 있기 때문에 구분해줄
필요가 없다.
join with on 으로
SELECT empno, ename, emp.deptno, dname
FROM emp JOIN dept ON ( emp.deptno = dept.deptno )
ORDER BY deptno
데이터결합 ( 실습 join 0 _ 1 )
emp , dept 테이블을 이용하여 조회하기
푸는 과정
1.emp와 dept를 먼저 조회해서 전체를 파악하고
SELECT *
FROM emp
SELECT *
FROM dept
2. emp 와 dept 에서 조회결과로 나올 애가 들어 있는 테이블을 확인해준다.
SELECT * empno, ename
FROM emp
SELECT * dname
FROM dept
공통으로 들어가는 것 deptno
여기에 추가된 조건이 : deptno 가 10이거나 30 인아이
ORACLE 로 풀기
SELECT empno, ename , emp.deptno , dname
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND emp.deptno in ( 10, 30 )
-NATURAL JOIN
SELECT empno, ename, deptno, dname
FROM emp NATURAL JOIN dept
WHERE deptno IN ( 10, 30 );
SELECT empno, ename, deptno, dname
FROM emp NATURAL JOIN dept
WHERE deptno = 10
OR deptno = 30
-JOIN WITH USING 으로
SELECT empno, ename, deptno, dname
FROM emp JOIN dept USING (deptno)
WHERE deptno IN ( 10, 30 );
- JOIN WITH ON 으로
SELECT empno, ename, emp.deptno, dname
FROM emp JOIN dept ON (emp.deptno = dept.deptno)
WHERE emp.deptno IN ( 10, 30 )
*진짜 중요한것 : join with USING 에서도 deptno같은 동일한 column에 한정자를
붙여주지 않아야 한다.
JOIN WITH ON 은 붙여줘야 한다.
데이터결합 ( 실습 join 0_3 )
1.ORACLE로 풀기
SELECT a.empno , a.ename , a.sal , a.deptno, b.dname
FROM emp a, dept b
WHERE a.deptno = b.deptno
AND sal > 2500
AND empno > 7600
2.NATURAL JOIN 으로 풀기
SELECT empno , ename , sal , deptno, dname
FROM emp NATURAL JOIN dept
WHERE sal > 2500
AND empno > 7600
natural join 에서는 동일한 컬럼인 deptno 에 한정자를 붙이면 안되고
또 동일한 컬럼이 deptno 뿐이니까 완전 한정자를 전체를 다 안붙여도 가능하고
한정자를 deptno 빼고 나머지에 붙여도 가능하다
SELECT a.empno , a.ename , a.sal , deptno, b.dname
FROM emp a NATURAL JOIN dept b
WHERE a.sal > 2500
AND a.empno > 7600
3. JOIN WITH USING 으로 풀기
SELECT a.empno , a.ename , a.sal , deptno, b.dname
FROM emp a JOIN dept b USING (deptno)
WHERE a.sal > 2500
AND a.empno > 7600 ;
* using 뒤에 ( ) 괄호 꼭 붙여야지 안붙이면 작동이 안되네
4. JOIN WITH ON 으로 풀기
-SELECT a.empno , a.ename , a.sal , a.deptno, b.dname
FROM emp a JOIN dept b ON ( a.deptno = b.deptno
AND a.sal > 2500
AND a.empno > 7600);
-SELECT a.empno , a.ename , a.sal , a.deptno, b.dname
FROM emp a JOIN dept b ON a.deptno = b.deptno
AND a.sal > 2500
AND a.empno > 7600;
데이터 결합 실습 JOIN0_4
EMP , DEPT 테이블 이용
oracle 이용 하기
SELECT e.empno, e.ename, e.sal, d.deptno, d.dname
FROM emp e , dept d
WHERE e.deptno = d.deptno
AND e.sal > 2500
AND e.empno >7600
AND d.dname = 'RESEARCH'
ORDER BY ename;
NATURAL JOIN 이용하기
SELECT e.empno, e.ename, e.sal, deptno, d.dname
FROM emp e NATURAL JOIN dept d
WHERE e.sal > 2500
AND e.empno >7600
AND d.dname = 'RESEARCH'
ORDER BY ename;
또는 NATURAL JOIN 은 공통된 COLUMN이 하나만 있는 애일때이고
deptno 에는 한정자를 붙이지 않아야 한다
공통된 column이 하나니까 다 한정자를 붙이지 않아도 무방
SELECT empno, ename, sal, deptno, dname
FROM emp NATURAL JOIN dept
WHERE sal > 2500
AND empno >7600
AND dname = 'RESEARCH'
ORDER BY ename;
JOIN WITH USING 이용하기
SELECT empno, ename, sal, deptno, dname
FROM emp JOIN dept USING (deptno)
WHERE sal > 2500
AND empno >7600
AND dname = 'RESEARCH'
ORDER BY ename ;
JOIN WITH ON 이용하기
진짜 중요한거는 : NATURAL JOIN 할때는 여기에 벌써 DEPTNO 라는 공통의 COLUMN 이 있기 때문에 em.deptno 와 dept.deptno 가 동일하다는 것은 안나타내
주어도 된다.
하지만 JOIN WITH ON이나 JOIN WITH USING 에서는 저부분을 명시해주어야 하고
그것을 표현하는 것은 JOIN WITH USING 에서는 뒤에 ( deptno )
JOIN WITH ON 에서는 ON뒤에 ( em.deptno = dept.deptno ) 을 명시해주어야 한다.
SELECT e.empno, e.ename, e.sal, d.deptno, d.dname
FROM emp e JOIN dept d ON e.deptno = d.deptno
AND e.sal > 2500
AND e.empno >7600
AND d.dname = 'RESEARCH'
ORDER BY ename;
댓글
댓글 쓰기