sql

[mysql] JOIN , SELF JOIN

scone 2022. 6. 25. 22:53

[JOIN 종류]

칼럼 갯수가 반드시 같아야 하는 UNION은 수직 결합 이었다면,
JOIN은 수평 결합을 생각하면 될 것 같다.

  • INNER JOIN                                   겹치는 테이블
  • FULL OUTER JOIN                        두 테이블 안의 모든 내용
  • LEFT JOIN                                      겹치는 테이블과 왼쪽 테이블 나머지
  • RIGHT JOIN                                   겹치는 테이블과 오른쪽 테이블 나머지

단, MYSQL 에서는 FULL OUTER JOIN 을 지원하지 않기 때문에 ( 다른 DBMS 에서는 지원 한다. )

조금 다른 형태의 (UNION 을 섞은) 쿼리문을 작성하여야 한다.

 

[사용할 테이블] 

CREATE TABLE snl_show
(
    ID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    SEASON int NOT NULL,
    EPISODE int NOT NULL,
    BROADCAST_DATE date,
    HOST varchar(32) NOT NULL
);

INSERT INTO snl_show VALUES
(1, 8, 7, '2020-09-05', '강동원'),
(2, 8, 8, 20200912, '유재석'),
(3, 8, 9, 20200919, '차승원'),
(4, 8, 10, 20200926, '이수현'),
(5, 9, 1, 20210904, '이병헌'),
(6, 9, 2, 20210911, '하지원'),
(7, 9, 3, 20210918, '제시'),
(8, 9, 4, 20210925, '조정석'),
(9, 9, 5, 20211002, '조여정'),
(10, 9, 6, '20211009', '옥주현');

그리고 이전에 썼던 celeb 테이블


[INNER JOIN] 

  • snl_show 호스트와 celeb name을 기준으로 INNER JOIN
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb
INNER JOIN snl_show
ON celeb.name = snl_show.host;

SELECT ...

FROM  왼쪽 테이블

INNER JOIN 오른쪽 테이블

ON 기준


[LEFT JOIN] 

  • 왼쪽 테이블에 다른 테이블을 포함하는 방식
  • name과 host를 기준으로 왼쪽 테이블 (celeb)에 오른쪽 테이블 (snl_show) 포함
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb                      ... right table
LEFT JOIN snl_show              ... left table
ON name = host;                  ... 유일한 이름의 칼럼일 경우 그냥 쓸수도 있음


[RIGHT JOIN] 

  • 오른쪽 테이블에 다른 테이블을 포함하는 방식
  • name과 host를 기준으로 오른쪽 테이블 (snl_show) 에 왼쪽 테이블 (celeb) 포함
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb                         ... left table
RIGHT JOIN snl_show                ... right table
ON celeb.name = snl_show.host;


[FULL OUTER JOIN] 

  • mysql에서는 관련 문법이 없기 때문에,
    LEFT JOIN 한 것과, RIGHT JOIN 한 것을 UNION 해줌으로써 구한다.
  • 모든 것의 합집합
  • name과 host를 기준으로 celeb과 snl_show 의 FULL OUTER JOIN 을 구해보자.
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb
LEFT JOIN snl_show
ON celeb.name = snl_show.host                                     ... left join
UNION
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb
RIGHT JOIN snl_show
ON celeb.name = snl_show.host;                                    ... right join


[SELF JOIN] 

  • INNER JOIN 과 그 기능이 같다.
  • 왼쪽 테이블과 오른쪽 테이블 구분이 없어진다.
  • 기존에 SELECT FROM 에서 WHERE 로 검색하는 거에서,
    하나 이상의 테이블에 대해 검색하는 거라고 생각하면 될 것 같다.
  • celeb.id, name, snl.id, host 에 대해서 celeb.id와 snl.id 가 같은 데이타 검색
SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
FROM celeb, snl_show
WHERE celeb.name = snl_show.host;

  • celeb 중 snl_show host로 출연했고, 영화 배우는 아니면서 YG 엔터테이먼트 소속 이거나 40세 이상이면서 YG 엔터테이먼트 소속이 아닌 연예인 이름과 나이, 직업, 소속사, 시즌, 에피소드 검색
    ( ALIAS 는 아직 안다뤘지만 너무 써야할게 많길래 그냥 썼다.)
SELECT c.name, c.age, c.job_title, c.agency, s.season, s.episode
FROM celeb as c, snl_show as s
WHERE c.name = s.host AND 
(( NOT c.job_title LIKE '%영화%' AND c.agency LIKE 'YG__%' ) OR
( age >= 40 AND NOT c.agency LIKE 'YG__%'));

  • snl에 출연한 celeb 중 에피소드 7, 9, 10 중에 출연했거나, 소속사가 YG로 시작하고 뒤에 6글자로 끝나는 사람 중 20년 9월 15일 이후에 출연했던 데이터
SELECT c.name, c.agency, s.episode, s.broadcast_date
FROM celeb c, snl_show s
WHERE c.name = s.host AND
(s.episode IN (7,9,10) OR c.agency LIKE 'YG______') AND
s.broadcast_date > 20200915;