본문으로 바로가기

JOIN

category DataBase/OracleDB 2020. 9. 3. 17:38

정규화

 : 하나로 되어 있는 것을 더 작은 조각으로 분리하는 기술

 : 관계형 DBMS에서 아주 중요한 기술

 : 정규화를 수행하면 하나의 테이블이 여러 개의 테이블들로 나누어짐

 

Join

 : 흩어져 있는 데이터들을 조합해서 가져오는 기술

 : 두 개 이상의 테이블을 가로로 연결하여 하나의 테이블처럼 출력할 때 사용하는 방식

 

Oracle JOIN

 : WHERE절에 적히는 조건을 JOIN조건이라고 부름

SELECT a.col1, b.col1
FROM table1 a, table2 b
WHERE a.col2=b.col2;

 

ANSI JOIN

 : Oracle Join과 다르게 FROM절에는 INNER JOIN 혹은 OUTER JOIN이 들어간다.

 : Join조건절에 WHERE절 대신 ON이 들어간다.

SELECT a.col1, b.col1
FROM tabl1 a [INNER] JOIN table2 b
ON a.col2=b.col2;

 

선행 테이블

 : driving table, inner table

 : 먼저 읽는 테이블

 : 조회할 데이터가 적은 테이블로 선택해야 속도 면에서 유리

 

후행 테이블

 : driven table, outer table

 : 뒤에 읽는 테이블

 

카티션 곱

 : Cartesion Product

 : Join 쿼리 중에 WHERE절에 기술하는 Join 조건이 잘못 기술되었거나 아예 없을 경우 발생하는 현상

 : ANSI SQL에서는 CROSS JOIN 이라고도 부름

 : Join 작업에 참조되는 테이블의 행 수를 모두 곱한 값 만큼 결과가 출력됨

 

(예제 테이블)

더보기

CREATE TABLE cat_a (no NUMBER, name VARCHAR2(1));
INSERT INTO cat_a VALUES(1, 'A');
INSERT INTO cat_a VALUES(2, 'B');
CREATE TABLE cat_b (no NUMBER, name VARCHAR2(1));
INSERT INTO cat_b VALUES(1, 'C');
INSERT INTO cat_b VALUES(2, 'D');
CREATE TABLE cat_c (no NUMBER, name VARCHAR2(1));
INSERT INTO cat_c VALUES(1, 'E');
INSERT INTO cat_c VALUES(2, 'F');

2개의 테이블로 정상저인 조인을 수행

 

2개의 테이블로 카티션 곱을 생성

 :  WHERE절로 Join 조건을 지정하지 않아서 모든 경우의 수가 다 나옴

 : cat_a X cat_b로 계산된 즉 2 X 2로 계산된 4건의 데이터가 나옴

3개의 테이블로 정상적인 조인을 수행

3개의 테이블을 조회하되 조인 조건절은 2개 테이블의 조건만으로 카디션 곱을 생성

 : 의도적으로 카디션 곱을 사용하는 경우도 많음

 : 사용하는 이유

  1. 데이터를 복제해서 원본 테이블을 반복해서 읽는 것을 피하기 위함

  2. 실수로 조인 조건 컬럼 중 일부를 빠뜨리는 경우

 

EQUI Join (등가 조인)

 : 가장 많이 사용되는 조인

 : 선행 테이블에서 데이터를 가져온 후 조인절을 검사해서

   동일한 조건을 가진 데이터를 후행 테이블에서 꺼내오는 방법

 : 조건절에서 Equal 연산자(=)를 사용

 : 내부 조인(Inner Join), 단순 조인(Simple Join)이라고 부르기도 함

 

 : Oracle Join 문법

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

 : ANSI Join 문법

 : 공통열이 한 개일때는 조건절 생략 가능

 

 : JOIN~ON

SELECT e.empno, e.ename, d.dname
FROM emp e JOIN dept d
ON e.deptno = d.deptno;

 

 : JOIN~USING

 : 기준열에 테이블을 명시하지 않음

SELECT deptno, e.empno, e.ename, d.dname
FROM emp e JOIN dept d USING(deptno)

 

 : 컬럼 이름이 하나의 테이블에만 있을 경우에는 테이블 이름을 생략해도 자동으로 테이블 이름을 찾아서 실행

 : 하지만 양 쪽 테이블에 모두 있는 컬럼일 경우 반드시 테이블 이름을 적어야함

 : 그러므로 Join SQL을 작성할 경우 반드시 "테이블명.컬럼명"으로 적는 습관을 들이는게 좋음

 

 

Non-Equi Join (비등가 조인)

 : 같은 조건이 아닌 크거나 작거나 하는 경우의 조건으로 조회를 할 때 사용 가능

  (Equal 연산자(=)를 사용하지 않고, 다른 연산자나 함수를 사용)

 

(customer 테이블)

더보기

create table customer
(gno  number(8) ,
 gname varchar2(30) ,
 jumin char(13) ,
 point number) ;

insert into customer values (20010001,'James Seo','7510231369824',980000);
insert into customer values (20010002,'Mel Gibson','7502241128467',73000);
insert into customer values (20010003,'Bruce Willis','7506152123648',320000);
insert into customer values (20010004,'Bill Pullman','7512251063421',65000);
insert into customer values (20010005,'Liam Neeson','7503031639826',180000);
insert into customer values (20010006,'Samuel Jackson','7601232186327',153000);
insert into customer values (20010007,'Ahnjihye','7604212298371',273000);
insert into customer values (20010008,'Jim Carrey','7609112118379',315000);
insert into customer values (20010009,'Morgan Freeman','7601202378641',542000);
insert into customer values (20010010,'Arnold Scharz','7610122196482',265000);
insert into customer values (20010011,'Brad Pitt','7711291186223',110000);
insert into customer values (20010012,'Michael Douglas','7704021358674',99000);
insert into customer values (20010013,'Robin Williams','7709131276431',470000);
insert into customer values (20010014,'Tom Hanks','7702261196365',298000);
insert into customer values (20010015,'Angela Bassett','7712141254963',420000);
insert into customer values (20010016,'Jessica Lange','7808192157498',598000);
insert into customer values (20010017,'Winona Ryder','7801051776346',625000);
insert into customer values (20010018,'Michelle Pfeiffer','7808091786954',670000);
insert into customer values (20010019,'Whoopi Goldberg','7803242114563',770000);
insert into customer values (20010020,'Emma Thompson','7802232116784',730000);

(gift 테이블)

더보기

create table gift
( gno  number ,
  gname varchar2(30) ,
  g_start  number ,
  g_end  number );

insert into gift values(1,'Tuna Set',1,100000);
insert into gift values(2,'Shampoo Set',100001,200000);
insert into gift values(3,'Car wash Set',200001,300000);
insert into gift values(4,'Kitchen Supplies Set',300001,400000);
insert into gift values(5,'Mountain bike',400001,500000);
insert into gift values(6,'LCD Monitor',500001,600000);
insert into gift values(7,'Notebook',600001,700000);
insert into gift values(8,'Wall-Mountable TV',700001,800000);
insert into gift values(9,'Drum Washing Machine',800001,900000);
insert into gift values(10,'Refrigerator',900001,1000000);

 : customer 테이블과 gift 테이블을 Join하여 고객별로 마일리지 포인트를 조회한 후 

  해당 마일리지로 받을 수 있는 상품을 조회

BETWEEN 보다는 비교 연산자를 사용하기를 권장함

 

OUTER Join (아우터 조인)

 : 한쪽 테이블에는 데이터가 있고 다른 한쪽 테이블에 데이터가 없느 경우에

   데이터가 있는 쪽 테이블의 내용을 전부 출력하게 하는 방법

 : Oracle Outer Join 문법은 SQL을 따로 작성한 후 UNION 연산자로 결과를 합쳐야함

 : ANSI Outer Join이 훨신 간단한 방법을 제공함

 : (저는 ANSI방법이 더 편해서 ANSI로만 설명하겠습니다.)

SELECT a.col, b.col
FROM AAA a [LEFT/RIGTH] OUTER JOIN BBB b
ON a.col = b.col;

 : LEFT 와 RIGTH는 데이터가 존재하는 쪽을 표시하기 위해 사용함

 

(student 테이블)

더보기

create table student
( studno number(4) primary key,
  name   varchar2(30) not null,
  id varchar2(20) not null unique,
  grade number check(grade between 1 and 6),
  jumin char(13) not null,
  birthday  date,
  tel varchar2(15),
  height  number(4),
  weight  number(3),
  deptno1 number(3),
  deptno2 number(3),
  profno  number(4)) tablespace users;

insert into student values (
9411,'James Seo','75true',4,'7510231901813',to_date('1975-10-23','YYYY-MM-DD'),'055)381-2158',180,72,101,201,1001);

insert into student values (
9412,'Rene Russo','Russo',4,'7502241128467',to_date('1975-02-24','YYYY-MM-DD'),'051)426-1700',172,64,102,null,2001);

insert into student values (
9413,'Sandra Bullock','Bullock',4,'7506152123648',to_date('1975-06-15','YYYY-MM-DD'),'053)266-8947',168,52,103,203,3002);

insert into student values (
9414,'Demi Moore','Moore',4,'7512251063421',to_date('1975-12-25','YYYY-MM-DD'),'02)6255-9875',177,83,201,null,4001);

insert into student values (
9415,'Danny Glover','Glover',4,'7503031639826',to_date('1975-03-03','YYYY-MM-DD'),'031)740-6388',182,70,202,null,4003);

insert into student values (
9511,'Billy Crystal','Crystal',3,'7601232186327',to_date('1976-01-23','YYYY-MM-DD'),'055)333-6328',164,48,101,null,1002);

insert into student values (
9512,'Nicholas Cage','Cage',3,'7604122298371',to_date('1976-04-12','YYYY-MM-DD'),'051)418-9627',161,42,102,201,2002);

insert into student values (
9513,'Micheal Keaton','Keaton',3,'7609112118379',to_date('1976-09-11','YYYY-MM-DD'),'051)724-9618',177,55,202,null,4003);

insert into student values (
9514,'Bill Murray','Murray',3,'7601202378641',to_date('1976-01-20','YYYY-MM-DD'),'055)296-3784',160,58,301,101,4007);

insert into student values (
9515,'Macaulay Culkin','Culkin',3,'7610122196482',to_date('1976-10-12','YYYY-MM-DD'),'02)312-9838',171,54,201,null,4001);

insert into student values (
9611,'Richard Dreyfus','Dreyfus',2,'7711291186223',to_date('1977-11-29','YYYY-MM-DD'),'02)6788-4861',182,72,101,null,1002);

insert into student values (
9612,'Tim Robbins','Robbins',2,'7704021358674',to_date('1977-04-02','YYYY-MM-DD'),'055)488-2998',171,70,102,null,2001);

insert into student values (
9613,'Wesley Snipes','Snipes',2,'7709131276431',to_date('1977-09-13','YYYY-MM-DD'),'053)736-4981',175,82,201,null,4002);

insert into student values (
9614,'Steve Martin','Martin',2,'7702261196365',to_date('1977-02-26','YYYY-MM-DD'),'02)6175-3945',166,51,201,null,4003);

insert into student values (
9615,'Daniel Day-Lewis','Day-Lewis',2,'7712141254963',to_date('1977-12-14','YYYY-MM-DD'),'051)785-6984',184,62,301,null,4007);

insert into student values (
9711,'Danny Devito','Devito',1,'7808192157498',to_date('1978-08-19','YYYY-MM-DD'),'055)278-3649',162,48,101,null,null);

insert into student values (
9712,'Sean Connery','Connery',1,'7801051776346',to_date('1978-01-05','YYYY-MM-DD'),'02)381-5440',175,63,201,null,null);

insert into student values (
9713,'Christian Slater','Slater',1,'7808091786954',to_date('1978-08-09','YYYY-MM-DD'),'031)345-5677',173,69,201,null,null);

insert into student values (
9714,'Charlie Sheen','Sheen',1,'7803241981987',to_date('1978-03-24','YYYY-MM-DD'),'055)423-9870',179,81,102,null,null);

insert into student values (
9715,'Anthony Hopkins','Hopkins',1,'7802232116784',to_date('1978-02-23','YYYY-MM-DD'),'02)6122-2345',163,51,103,null,null);

(professor 테이블)

더보기

이메일주소 및 주소가 하이퍼링크 걸려서 파일로 올렸습니다.

professor.txt
0.00MB

OUTER JOIN 주의사항

 : WHERE절에 기술한 조건은 기준 테이블의 집합의 수를 결정

 : ON절에 기술한 조건은 기준 집합 중에 아우터 조인 대상이 되는 집합을 말하는 것

   (전체 결과 집합에는 아무런 영향을 주지 않는다.)

 

 : LEFT OUTER JOIN - 왼쪽에 있는 테이블을 기준으로 데이터를 보고자 할 때 사용

 : RIGHT OUTER JOIN - 오른쪽에 있는 테이블을 기준으로 데이터를 보고자 할 때 사용

 : FULL OUTER JOIN - 양쪽 테이블에 있는 데이터를 모두 보고자 할 때 사용

 

 

 

SELF Join

 : 데이터를 가지고 있는 하나의 테이블을 메모리에서 별명 두 개로 사용해서 호출하는 방법

 : 하나의 테이블을 두 개의 테이블로 만들어 일반적인 Join 작업을 수행하면 됨

SELECT a1.name, a2.name
FROM AAA a1 JOIN AAA a2
ON a1.col1 = a2.col2;

 : 해당 empno의 상위부서를 조회

반응형

'DataBase > OracleDB' 카테고리의 다른 글

DDL 명령과 딕셔너리  (0) 2020.09.04
Constraint (제약 조건)  (0) 2020.09.04
복수행 함수  (0) 2020.09.02
단일행 함수  (0) 2020.09.01
SELECT  (0) 2020.08.31