정규화
: 하나로 되어 있는 것을 더 작은 조각으로 분리하는 기술
: 관계형 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하여 고객별로 마일리지 포인트를 조회한 후
해당 마일리지로 받을 수 있는 상품을 조회
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 테이블)
이메일주소 및 주소가 하이퍼링크 걸려서 파일로 올렸습니다.
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 |