JOIN

철칙!! : 앞테이블 데이터가 작아야함


 문법)

 SELECT table1.column, table2.column

 FROM  table1, table2

 WHERE condition;



카티션 곱 (Cartesian Product)

  두개 이상의 테이블에 대해 연결 가능한 행을 모두 결합하는 조인방법.

  WHERE 절에서 조인 조건절을 생략하거나 조인 조건을 잘못 설정하여 양쪽 테이블을 연결하는 조건을 만족하는 행이 하나도 없는 경우에 발생한다.




예제 : 학생 테이블과 부서 테이블을 카티션 곱을 한 결과를 출력하여라.

SQL> SELECT name, student.deptno, dname, loc

     FROM student, department;


위 문장을 실행하면 112개의 행이 나온다. 위 쿼리문에서 WHERE 조건이 없어서 생긴 문제이며 항상 이런 상황이 발생하지 않도록 주의해야 한다.




EQUI JOIN

 SQL 문에서 가장 많이 사용되는 조인으로 조인 대상 테이블에서 공통칼럼을

 '=' 비교를 통해 같은 값을 갖는 행을 연결하여 결과를 생성하는 조인 방법임.


문법)

 SELECT    table1.column, table2.column

 FROM       table1, table2

 WHERE     table1.column = table2.column;



예제 : 학생 테이블과 부서 테이블을 EQUI JOIN 하여

       학번, 이름, 학과번호, 소속학과 이름, 학과 위치를 출력하여라.

SQL> SELECT s.studno, s.name, s.deptno, d.dname, d.loc

     FROM  student s, department d

     WHERE s.deptno = d.deptno


문제 : student 테이블과 department 테이블을 사용하여 학생명과 학과명을 출력하세요

SQL> select s.name 학생이름, d.dname 학과이름

     from student s,department d

     where s.deptno=d.deptno;


학생이름             학과이름

-------------------- --------------------------------

전인하               컴퓨터공학과

이동훈               전자공학과

박미경               컴퓨터공학과

김영균               컴퓨터공학과

박동진               전자공학과

김진영               멀티미디어학과

지은경               컴퓨터공학과

오유석               멀티미디어학과

하나리               멀티미디어학과

임유진               컴퓨터공학과

서재진               컴퓨터공학과

윤진욱               멀티미디어학과

이광훈               컴퓨터공학과

김진경               전자공학과

조명훈               전자공학과

류민정               컴퓨터공학과


16 rows selected.



문제 : Student , department , professor 테이블을 사용하여 학생이름,학과이름,지도교수이름을 아래와 같이 출력하세요.

SQL> select s.name 학생이름, d.dname 학과이름, p.name 지도교수명

     from student s,department d, professor p

     where s.deptno=d.deptno and s.profno=p.profno


학생이름             학과이름                         지도교수명

-------------------- -------------------------------- --------------------

김진경               전자공학과                       이재우

이광훈               컴퓨터공학과                     성연희

전인하               컴퓨터공학과                     성연희

윤진욱               멀티미디어학과                   권혁일

오유석               멀티미디어학과                   권혁일

김진영               멀티미디어학과                   권혁일

김영균               컴퓨터공학과                     이만식

류민정               컴퓨터공학과                     전은지

임유진               컴퓨터공학과                     전은지

지은경               컴퓨터공학과                     전은지


10 rows selected.




NON-EQUI JOIN

 조인 조건에서 '<',BETWEEN a AND b 와 같이 '=' 조건이 아닌 다른 종류의

 연산자를 사용하는 조인 방법이다. 그다지 많이 사용되지는 않는다.


예제 : 교수 테이블과 급여 등급 테이블을 NON-EQUI JOIN 하여 교수별로 급여등급을 출력하여라.

SQL> SELECT p.profno, p.name, p.sal, s.grade

     FROM professor p,salgrade s

     WHERE p.sal BETWEEN s.losal AND s.hisal;




Test13 , test14 테이블을 사용하여

문제1) 고객별로 받을 수 있는 상품을 출력하고

CUST                     GIFT

-------------- -----------

771201-2233445    COMPUTER

620908-2121232    COMPUTER

500823-1132762    AUDIO

672102-2123452    의류교환권

650207-1765152    굴비세트

680801-1234455    갈비세트

…………………………..

***************************************

SQL> select t14.cust, t13.gift

     from test13 t13, test14 t14

     where t14.point between t13.fpoint and t13.tpoint;


CUST                         GIFT

---------------------------- ---------------

771201-2233445               COMPUTER

620908-2121232               COMPUTER

500823-1132762               AUDIO

672102-2123452               의류교환권

650207-1765152               굴비세트

680801-1234455               갈비세트

701212-1143211               PCS무료가입권

710125-1144951               구두상품권

721109-2144952               녹차세트

721101-2144952               도서상품권


10 rows selected.

*****************************************



문제2)각 상품이 몇 개가 필요한지 출력하세요.


GIFT                     COUNT(A.CUST)

--------------  -------------

COMPUTER                        2

의류교환권                      1

굴비세트                        1

갈비세트                        1

PCS무료가입권                   1

…………………………..

******************************************************

SQL> select t13.gift, count(t14.cust)

     from test13 t13,test14 t14

     where t14.point between t13.fpoint and t13.tpoint

     group by t13.gift;


GIFT                                              COUNT(T14.CUST)

------------------------------------------------ ---------------

COMPUTER                                                       2

의류교환권                                                     1

굴비세트                                                       1

갈비세트                                                       1

PCS무료가입권                                                  1

구두상품권                                                     1

AUDIO                                                          1

녹차세트                                                       1

도서상품권                                                     1


9 rows selected.

***********************************************************



Test13 , test14 테이블을 참조하여

문제 : 고객의 포인트보다 낮은 모든 모든 등급의 상품을 선택할 수 있다고 할때 갈비세트를 상품으로 받을 수 있는 고객의 고객번호, 포인트 , 선물을 보여주는 쿼리를 작성하시오.


CUST                       POINT        GIFT

-------------- ---------- ----------

650207-1765152    20239650      갈비세트

672102-2123452    40935040      갈비세트

500823-1132762    75636408      갈비세트

771201-2233445   129855120     갈비세트

680801-1234455    10059470      갈비세트

620908-2121232   123674200     갈비세트


6 rows selected.


SQL> select cust,point,gift

     from test14 b, test13 a

     where a.fpoint <= b.point

     and a.gift = '갈비세트';


CUST                              POINT GIFT

---------------------------- ---------- ------

650207-1765152                 20239650 갈비세트

672102-2123452                 40935040 갈비세트

500823-1132762                 75636408 갈비세트

771201-2233445                129855120 갈비세트

680801-1234455                 10059470 갈비세트

620908-2121232                123674200 갈비세트


6 rows selected.





문제 : temp 테이블의 사람 중 emp_level 테이블에서의 부장직급을 받아야 할 나이를 가지고 있는 사람의 사번,성명,생일,현재나이,현재 직급을 출력하세요.

SQL> select a.emp_id "사번", a.emp_name "이름",

               to_char(a.birth_date,'YYYY-MM-DD') "생년월일",

               trunc(months_between(sysdate,a.birth_date)/12) "현재나이", a.lev "현재직급"

     from temp a, emp_level b

     where trunc(months_between(sysdate,a.birth_date)/12)

                between b.from_age and b.to_age

                and b.lev='부장';


      사번 이름                 생년월일               현재나이 현재직급

---------- -------------------- -------------------- ---------- --------

  19970101 김길동               1974-01-25                   37 부장

  19960101 홍길동               1973-03-22                   38 과장

  19970201 박문수               1975-04-15                   36 과장

  19930331 정도령               1976-05-25                   35 차장

  19950303 이순신               1973-06-15                   38 대리

  19966102 지문덕               1972-07-05                   39 과장

  19930402 강감찬               1972-08-15                   39 차장

  .......

  20000102 김설악               1980-03-22                   31 수습

  20000203 최오대               1980-04-15                   31 수습

  20000334 박지리               1980-05-25                   31 수습

  20000305 정북악               1980-06-15                   31 수습

  20006106 유도봉               1980-07-05                   31 수습

  20000407 윤주왕               1980-08-15                   31 수습

  20000308 강월악               1980-09-25                   31 수습

  20000119 장금강               1980-11-05                   31 수습

  20000210 나한라               1980-12-15                   31 수습

20 rows selected.

*********************

SQL> select a.emp_id "사번",a.emp_name "성명", a.birth_date "생일",

            to_char(sysdate,'yyyy')-to_char(a.birth_date,'yyyy') "현재나이", a.lev

     from temp a, emp_level b

     where to_char(sysdate,'yyyy')-to_char(a.birth_date,'yyyy') >= b.from_age

           and b.lev = '부장';




(+) 기호를 사용한 OUTER JOIN

NULL이 출력되는 칼럼에 (+) 기호를 추가하면 된다

OUTER JOIN 연산자 (+)는 NULL이 존재하는 칼럼 쪽에 표시한다.




예제 : 학생 테이블과 교수 테이블을 조인하여 이름, 학년, 지도 교수의 이름, 직급을 출력하여라.

       단, 지도 교수가 배정되지 않은 학생이름도 함께 출력하여라.


SQL> SELECT s.name sname, s.grade, p.name pname, p.position

     FROM         student s, professor p

     WHERE       s.profno = p.profno(+)

     ORDER BY  p.profno;



문제 : 학생테이블과 교수테이블을 조인하여 이름, 학년,지도교수 이름,직급을 출력하세요.

       단, 지도학생을 배정받지 않은 교수이름도 함께 출력하세요.

SQL> select s.name, s.grade, s.name, p.position

     from student s,professor p

     where s.profno(+)=p.profno;


NAME                 GR NAME                 POSITION

-------------------- -- -------------------- ----------------------------------------

전인하               4  전인하               조교수

김영균               3  김영균               부교수

김진영               2  김진영               교수

지은경               2  지은경               전임강사

오유석               4  오유석               교수

임유진               2  임유진               전임강사

윤진욱               3  윤진욱               교수

이광훈               4  이광훈               조교수

김진경               2  김진경               조교수

류민정               2  류민정               전임강사

                                             교수

                                             전임강사

                                             부교수


13 rows selected.




SQL> select s.name, s.grade, s.name, p.position

     from student s,professor p

     where s.profno=p.profno(+);


NAME                 GR NAME                 POSITION

-------------------- -- -------------------- ----------------------------------------

김진경               2  김진경               조교수

이광훈               4  이광훈               조교수

전인하               4  전인하               조교수

윤진욱               3  윤진욱               교수

오유석               4  오유석               교수

김진영               2  김진영               교수

김영균               3  김영균               부교수

류민정               2  류민정               전임강사

임유진               2  임유진               전임강사

지은경               2  지은경               전임강사

조명훈               1  조명훈

서재진               1  서재진

하나리               1  하나리

박동진               1  박동진

박미경               1  박미경

이동훈               1  이동훈


16 rows selected.


SQL> select s.name " 이름", s.grade "학년", p.name "지도교수 이름", p.position "직급"

     from student s, professor p

     where s.profno(+) = p.profno;



문제 : Temp 테이블과 emp_level 테이블을 조인하여 각 사원의 사번,이름,직급,현재연봉,해당 직급의 연봉의 상,하한금액을 보고자 한다. 단 연봉의 상,하한이 결정 안 된 수습사원은 사번,이름,직급,현재연봉만 나오면 된다. 쿼리를 만들어보세요.

SQL> select t.emp_id,t.emp_name,t.lev,t.salary,e.from_sal,e.to_sal

     from temp t, emp_level e

     where t.lev=e.lev(+);


    EMP_ID EMP_NAME             LEV          SALARY   FROM_SAL     TO_SAL

---------- -------------------- -------- ---------- ---------- ----------

  19960303 설까치               사원       35000000   30000000   40000000

  19970112 연흥부               대리       45000000   35000000   60000000

  19950303 이순신               대리       56000000   35000000   60000000

  19960212 배뱅이               과장       39000000   37000000   75000000

  19966102 지문덕               과장       45000000   37000000   75000000

  19970201 박문수               과장       50000000   37000000   75000000

  19960101 홍길동               과장       72000000   37000000   75000000

  19930402 강감찬               차장       64000000   40000000   80000000

  19930331 정도령               차장       70000000   40000000   80000000

  19970101 김길동               부장      100000000   60000000  100000000

  20000210 나한라               수습       30000000

  20000119 장금강               수습       30000000

  20000308 강월악               수습       30000000

  20000407 윤주왕               수습       30000000

  20006106 유도봉               수습       30000000

  20000305 정북악               수습       30000000

  20000334 박지리               수습       30000000

  20000203 최오대               수습       30000000

  20000102 김설악               수습       30000000

  20000101 이태백               수습       30000000


20 rows selected.

***************************************************************************


SQL> select a.emp_id "사번", a.emp_name "이름", a.lev "직급", a.salary "현재연봉",

                                b.from_sal "하한", b.to_sal "상한"

     from temp a, emp_level b

     where a.lev = b.lev(+);

셀프조인

하나의 테이블에서 두 개의 칼럼을 연결하여 조인



예제 : 부서번호가 201 이상인 부서 이름과 해당 부서가 소속된 상위 부서의 이름을 출력하여라.

SQL> SELECT dept.dname || ' is belong to ' || org.dname

     FROM    department dept, department org

     WHERE   dept.college = org.deptno

     AND    dept.deptno >= 201;




문제 : 학번이 10101 인 학생의 학번, 이름, 학과이름과 학과 위치를 출력하시오.

SQL> select s.studno,s.name,d.dname,d.loc

     from student s, department d

     whre s.deptno = d.deptno    ← join조건

     and s.studno = 10101;       ← 검색조건




문제 : 몸무게가 80kg 이상인 학생의 학번, 이름, 체중, 학과이름, 학과위치를 출력하여라.

SQL> select s.studno, s.name, s.weight, d.dname, d.loc

     from student s,department d

     where s.deptno=d.deptno and s.weight>=80;




문제 : Self join, outer join , non-equi join을 이용하여 temp 테이블을 이용하여 아래 조건의 쿼리를 작성하시오. Temp 테이블을 사용해 사번, 성명, 생일, 자신보다 생일이 빠른 사람수를 조회하여 자신보다 생일이 빠른 사람 수 순서대로 오름차순으로 정렬해서 출력하라.

SQL> select a.emp_id "사번", a.emp_name "이름",

                             a.birth_date "생일", count(b.birth_date) "빠른사람수"

      from temp a,temp b

      where b.birth_date(+) < a.birth_date

      group by a.emp_id, a.emp_name, a.birth_date

      order by count(b.birth_date);


SQL> select a.emp_id, a.emp_name, a.birth_date,count(b.birth_date)

     from temp a, temp b

     where a.birth_date > b.birth_date(+)

     group by a.emp_id, a.emp_name, a.birth_date

     order by 4;

안시조인

비  교

오라클 조인

안시조인

select ~~~

from a , b

where ~~~

select ~~~

from a join b

on ~~~

 

 

아우터 조인 비교

오라클 조인

안시조인

Null 쪽에 (+)

LEFT OUTER JOIN

RIGHT OUTER JOIN

FULL OUTER JOIN

 

예  제

 

SELECT e.last_name, e.department_id, d.department_name

FROM   employees e LEFT OUTER JOIN departments d

ON   (e.department_id = d.department_id) ;

 

 

SELECT e.last_name, e.department_id, d.department_name

FROM   employees e RIGHT OUTER JOIN departments d

ON    (e.department_id = d.department_id) ;

 

SELECT e.last_name, d.department_id, d.department_name

FROM   employees e FULL OUTER JOIN departments d

ON   (e.department_id = d.department_id) ;

연습문제

1. EQUI JOIN 을 이용하여 학생 이름과 소속 학과 이름을 학과 이름, 학생 이름순

    으로 정렬하여 출력하시오.

SQL> select s.name, d.dname

     from student s,department d

     where s.deptno=d.deptno

     order by 1



2. OUTER JOIN을 이용하여 101번 학과에 소속된 학생들의 이름과 지도 교수

   이름을 출력 하세요. 이때 지도교수가 배정되지 않은 학생도 함께 출력하세요.

SQL> select s.name "학생", p.name "지도교수"

     from student s,professor p

     where s.profno = p.profno(+);



3. 공과대학에 소속된 학부와 학과 이름을 출력하세요.


DNAME                                DEPTNO DNAME

-------------------------------- ---------- --------------------------------

정보미디어학부                          100 멀티미디어학과

정보미디어학부                          100 컴퓨터공학과

메카트로닉스학부                        200 기계공학과

메카트로닉스학부                        200 전자공학과


SQL> select b.dname,b.deptno,c.dname

     from department a, department b, department c

     where b.deptno = c.college

     and a.deptno = b.college

     and a.deptno =10;




4. 각 학과별로 학과번호 , 학과 이름, 소속 학생 이름, 학생의 지도교수 이름,

    지도교수 직급, 지도교수 소속 학과번호 , 지도교수소속 학과명을 출력하세요

   (단 지도교수가 없는 학생과 지도 학생이 없는 교수 모두 출력하세요)

결과)

deptno dname          name   name   position  deptno dname

------ ---------------- ------- ------- --------- ------ -----

101    컴퓨터공학과   김영균 이만식 부교수   101   컴퓨터공학과

101    컴퓨터공학과     류민정  전은지  전임강사  101    컴퓨터공학과

101    컴퓨터공학과     박미경      

101    컴퓨터공학과     서재진

...

19 row


SQL> select d.deptno, d.dname, s.name, p.name,

            p.position, dept.deptno, dept.dname

     from student s

     full outer join professor p on p.profno = s.profno

     left outer join department d on d.deptno = s.deptno

     left outer join department dept on dept.deptno = p.deptno

     order by 1,3;



    DEPTNO DNAME             NAME      NAME      POSITION     DEPTNO DNAME

---------- ----------------- --------- --------- ----------  ------- ---------------

       101 컴퓨터공학과      김영균    이만식    부교수         101 컴퓨터공학과

       101 컴퓨터공학과      류민정    전은지    전임강사       101 컴퓨터공학과

       101 컴퓨터공학과      박미경

       101 컴퓨터공학과      서재진

       101 컴퓨터공학과      이광훈    성연희    조교수         101 컴퓨터공학과

       101 컴퓨터공학과      임유진    전은지    전임강사       101 컴퓨터공학과

       101 컴퓨터공학과      전인하    성연희    조교수         101 컴퓨터공학과

       101 컴퓨터공학과      지은경    전은지    전임강사       101 컴퓨터공학과

       102 멀티미디어학과    김진영    권혁일    교수           102 멀티미디어학과

       102 멀티미디어학과    오유석    권혁일    교수           102 멀티미디어학과

       102 멀티미디어학과    윤진욱    권혁일    교수           102 멀티미디어학과

       102 멀티미디어학과    하나리

       201 전자공학과        김진경    이재우    조교수         201 전자공학과

       201 전자공학과        박동진

       201 전자공학과        이동훈

       201 전자공학과        조명훈

                                       염일웅    전임강사       102 멀티미디어학과

                                       김도훈    교수           101 컴퓨터공학과

                                       남은혁    부교수         202 기계공학과


19 rows selected.





5. 교수 테이블에서 학과번호 ,교수 이름, 교수 별 지도 학생 수 , 학과별 소계학생수, 

   총 학생수를  출력하세요.


SQL> select p.deptno, p.name, count(*)

  2  from professor p, student s

  3  where p.profno = s.profno

  4  group by rollup(p.deptno,p.name);


    DEPTNO NAME                   COUNT(*)

---------- -------------------- ----------

       101 성연희                        2

       101 이만식                        1

       101 전은지                        3

       101                               6

       102 권혁일                        3

       102                               3

       201 이재우                        1

       201                               1

                                        10


9 rows selected.

'Oracle > Oracle - SQL' 카테고리의 다른 글

SQL정리 8장 DML  (0) 2012.01.10
SQL정리 7장 서브쿼리  (0) 2012.01.09
SQL정리 5장 그룹함수  (0) 2012.01.05
SQL정리 4장 함수  (0) 2012.01.04
SQL정리 1-3장  (0) 2012.01.04
Posted by 딩구르
,