본문 바로가기

DATA BASE

JOIN (CERTESIAN JOIN, INNER JOIN, OUTER JOIN)

ANSI JOIN

: 표준 문법

장점 - MIGRATION할 때 좋아요 (Mysql -> 마리아)

 

데이터 베이스 오라클 문법 비싸지만 더 좋은 기능들이 많아요!

마리아 무료

 

오라클 DB

테이블의 한 행(레코드) = 오브젝트

->오브젝트를 저장 할 수 없으니까

->FK 

 

PK 유니크함 - 한테이블에 여러개 만들 수는 있지만 그렇게 하지마!

FK 참조

 

제약 조건 (Constraint)

외례키

 

 

 

CERTESIAN JOIN

 

14개

4개

14 x 4 = 56


INNER JOIN

 

예시 하나더

 

SELECT * 
FROM PROFESSOR P , STUDENT S
WHERE P.PROFNO = S.PROFNO;

 

담당교수 목록만 보자!

SELECT S.NAME, P.NAME
FROM STUDENT S, PROFESSOR P 
WHERE S.PROFNO = P.PROFNO;

 

 


OUTER JOIN

모든 사진을 출력하면서 댓글수를 같이 표시하고 싶다면?

 

게시판 내용을 댓글 없는 것도 다 보이고 싶으면 아우터 조인이다!

 

 

테이블

 

DDL - 테이블 삭제(DROP), 수정(ALTER), 생성(CREATE)

데이터의 순서 (Users -> Board -> Reply)

CREATE TABLE USERS(
    id number,
    username varchar2(20) not null,
    email varchar2(50) not null,
    CONSTRAINT USERS_PK PRIMARY KEY (id)
);

CREATE TABLE BOARD(
    id number,
    title varchar2(100) not null,
    content varchar2(1000) not null,
    userId number,
    CONSTRAINT BOARD_PK PRIMARY KEY (id),
    CONSTRAINT BOARD_FK_USER_ID FOREIGN KEY (userId) REFERENCES Users (id)
);

CREATE TABLE Reply(
    id number,
    content varchar2(200) not null,
    boardId number,
    userId number,
    CONSTRAINT REPLY_PK PRIMARY KEY (id),
    CONSTRAINT REPLY_FK_BOARD_ID FOREIGN KEY (boardId) REFERENCES Board (id),
    CONSTRAINT REPLY_FK_USER_ID FOREIGN KEY (userId) REFERENCES Users (id)
);

 

시퀀스

 

CREATE SEQUENCE users_seq
INCREMENT BY 1
START WITH 1;  

CREATE SEQUENCE board_seq
INCREMENT BY 1
START WITH 1; 

CREATE SEQUENCE reply_seq
INCREMENT BY 1
START WITH 1;

데이터

-- Users, Board, Reply
-- DML (데이터 조작어)
INSERT INTO USERS(ID, USERNAME, EMAIL) 
VALUES(USERS_SEQ.nextval, 'ssar', 'ssar@nate.com');

INSERT INTO USERS(ID, USERNAME, EMAIL) 
VALUES(USERS_SEQ.nextval, 'love', 'love@nate.com');

INSERT INTO USERS(ID, USERNAME, EMAIL) 
VALUES(USERS_SEQ.nextval, 'cos', 'cos@nate.com');

commit;

SELECT * FROM USERS;

INSERT INTO BOARD(ID, TITLE, CONTENT, USERID) 
VALUES(BOARD_SEQ.nextval, '오라클 1강', 'DDL이란?', 1);

INSERT INTO BOARD(ID, TITLE, CONTENT, USERID) 
VALUES(BOARD_SEQ.nextval, '오라클 2강', 'DML이란?', 1);

INSERT INTO BOARD(ID, TITLE, CONTENT, USERID) 
VALUES(BOARD_SEQ.nextval, '오라클 3강', 'DCL이란?', 2);

INSERT INTO BOARD(ID, TITLE, CONTENT, USERID) 
VALUES(BOARD_SEQ.nextval, '오라클 4강', 'DQL이란?', 1);

COMMIT;

SELECT * FROM BOARD;

INSERT INTO REPLY(ID, CONTENT, BOARDID, USERID) 
VALUES(REPLY_SEQ.nextval, '재밌어요', 1, 1);

INSERT INTO REPLY(ID, CONTENT, BOARDID, USERID) 
VALUES(REPLY_SEQ.nextval, '진짜 재밌어요', 1, 2);

COMMIT;

SELECT * FROM REPLY;

 

 

이너 쿼리

 

SELECT * 
FROM USERS U, BOARD B
WHERE U.ID = B.USERID;

이너 쿼리 하나 더

SELECT B.ID, B.TITLE, B.USERID, R.CONTENT
FROM BOARD B, REPLY R
WHERE B.ID = R.BOARDID;

 

 

아우터 쿼리

 

SELECT B.ID, B.TITLE, B.USERID, R.CONTENT
FROM BOARD B, REPLY R
WHERE B.ID = R.BOARDID(+);

 

 

 

 

쿼리 (3개 이상 조인 + GROUP BY 활용)

 

 

SELECT B.ID, B.TITLE, U.USERNAME, COUNT(R.ID) "댓글수"
FROM BOARD B, REPLY R, USERS U
WHERE B.ID = R.BOARDID(+) AND B.USERID = U.ID
GROUP BY B.ID, B.TITLE, U.USERNAME;

하나 더

 

SELECT ID, TITLE, USERID,
(SELECT COUNT(*) FROM REPLY WHERE BOARDID = B.ID) "댓글수"
FROM BOARD B;

 

 

 

 

 

 

 

 

집합 연산자

 

union all - 그냥 갖다 붙이기

union 비추(중복제거 후 정렬해줘서 연산많아서 느림)

intersect -교집합 결과 출력 후 정렬

minus - 차집합 결과 출력 후 정렬. 쿼리 순서 신경쓰기