[SQL] UNION, JOIN

쩡이·2023년 8월 23일
0

SQL

목록 보기
4/10

UNION

여러 개의 쿼리를 합쳐서 하나의 SQL문으로 만들어 준다. 단, 컬럼의 개수가 같아야 함 종류는 상관x

UNION : 중복된 값을 제거하여 보여줌

UNION ALL : 중복된 값을 포함하여 모두 보여줌

select column1, column2, ... from table1
UNION|UNION ALL
select column1, column2, ... from table2;

#예제1
성별이 여자인 데이터를 검색하는 쿼리와 
소속사가 YG엔터ㅔ이먼트인 데이터를 검색하는 쿼리를 UNION ALL로 실행
select name,sex,agency from celeb where sex='F'
UNION ALL
select name,sex,agency from celeb where agency='YG엔터테이먼트';

#예제2
성별이 여자인 데이터를 검색하는 쿼리와 
소속사가 YG엔터ㅔ이먼트인 데이터를 검색하는 쿼리를 UNION으로 실행
select name,sex,agency from celeb where sex='F'
UNION
select name,sex,agency from celeb where agency='YG엔터테이먼트';


#예제3
가수가 직업인 연예인의 이름, 직업을 검색하는 쿼리와 1980년대에 태어난 연예인의 이름, 생년월일, 나이를 검색하는 쿼리를 UNION으로 실행
select name, job_title from celeb where job_title like '%가수%'
UNION
select name, birthday, age from celeb where birthday BETWEEN 19800101 AND 19891231;

<출력결과>
컬럼수가 달라서 에러발생함, 컬럼수를 같게 해서 출력해도, 컬럼 종류가 다르다면 컬럼명과 value값이 맞지 않는 결과가 나옴
#문제1
직업이 가수인 데이터를 검색하는 쿼리와
직업이 탤런트인 데이터를 검색하는 쿼리를 중복을 제거하여 합쳐서 실행
select name, job_title from celeb where job_title LIKE '%가수%'
UNION
select name, job_title from celeb where job_title LIKE '%탤런트%';


#문제2
성이 이씨인 데이터를 검색하는 쿼리와
1970년대생을 검색하는 쿼리를 중복을 포함하여 합쳐서 실행
select name, birthday from celeb where name LIKE '이%'
UNION ALL
select name, birthday from celeb where birthday BETWEEN 19700101 AND 19791231;

JOIN

실습환경 만들기

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
);
#AUTO_INCREMENT:입력 하지 않으면 자동으로 증가되는 값을 넣는다.
#PRIMARY KEY : 프라이머리 키로 지정한다.
#varchar : 예측할 수 없는 가변적 문자열
#char : 고정길이 문자열
insert into snl_show values (1, 8, 7, '2020-09-05', '강동원');
insert into snl_show values (2, 8, 8, '2020-09-12', '유재석');
insert into snl_show values (3, 8, 9, '2020-09-19', '차승원');
insert into snl_show values (4, 8, 10, '2020-09-26', '이수현');
insert into snl_show values (5, 9, 1, '2021-09-04', '이병헌');
insert into snl_show values (6, 9, 2, '2021-09-11', '하지원');
insert into snl_show values (7, 9, 3, '2021-09-18', '제시');
insert into snl_show values (8, 9, 4, '2021-09-25', '조정석');
insert into snl_show values (9, 9, 5, '2021-10-02', '조여정');
insert into snl_show values (10, 9, 6, '2021-10-09', '옥주현');


INNER JOIN

두 개의 테이블에서 공통된 요소들을 통해 결합하는 조인 방식, 교집합
select column1, column2, ... 가져올 컬럼명
from tableA
INNER JOIN tableB
ON tableA.column = tableB.column : on 기준을 정해줌, 같은 컬럼명이 존재할 경우 컬럼명 앞에 테이블명을 꼭 적어야 함, 컬럼명이 다르면 테이블명 생략가능
(where condition); 선택사항

예제
snl_show에 호스트로 출연한 celeb을 기준으로 
celeb 테이블과 snl_show 테이블을 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;


LEFT JOIN

두 개의 테이블에서 공통영역과 왼쪽 테이블의 나머지 데이터를 포함하여 조인하는 방식 즉, 왼쪽 전체 데이터를 포함하는 조인방식
select column1, column2, ...
from tableA from 다음에 오는 테이블 : left table
LEFT JOIN tableB right table
ON tableA.column = tableB.column
(where condition); 선택사항

#예제
snl_show에 호스트로 출연한 celeb을 기준으로 
celeb 테이블과 snl_show 테이블을 left 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 table의 모든 데이터가 포함되기 때문에 snl_show에 출연하지 않은 celeb은 null값을 가진다.


RIGHT JOIN

두 개의 테이블에서 공통영역과 오른쪽 테이블의 나머지 데이터를 포함하여 조인하는 방식 즉, 오른쪽 전체 데이터를 포함하는 조인방식
select column1, column2, ...
from tableA left table
RIGHT JOIN tableB right table
ON tableA.column = tableB.column
(where condition); 선택사항

예제
snl_show에 호스트로 출연한 celeb을 기준으로 
celeb 테이블과 snl_show 테이블을 right join 

select celeb.id, celeb.name, snl_show.id, snl_show.host
from celeb
RIGHT JOIN snl_show
ON celeb.name=snl_show.host;

right table의 모든 데이터가 포함되므로 celeb(left table)이 아닌 사람들은 null값을 가진다.


FULL OUTER JOIN

두 개의 테이블에서 공통영역을 포함하여 양쪽 테이블의 다른영역을 모두 포함하는 조인방식
합집합
select column1, column2, ...
from tableA left table
FULL OUTER JOIN tableB right table
ON tableA.column = tableB.column
(where condition); 선택사항

MySQL에서는 FULL JOIN을 지원하지 않음
left join, right join을 union으로 묶어주면 FULL JOIN 기능을 대신함

select column1, column2, ...
from tableA
LEFT JOIN tableB ON tableA.column = tableB.column
UNION
select column1, column2, ...
from tableA
RIGHT JOIN tableB ON tableA.column = tableB.column
(where condition);
예제
snl_show에 호스트로 출연한 celeb을 기준으로 
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
UNION
select celeb.id, celeb.name, snl_show.id, snl_show.host
from celeb
RIGHT JOIN snl_show 
ON celeb.name = snl_show.host;


SELF JOIN

가장 많이 사용되는 조인방식, inner join과 같은 결과를 가져옴
select column1, column2, ...
from tableA, tableB, ... 테이블이 여러개 올 수 있음
where condition; where절에 기준 제시

#예제1
snl_show에 호스트로 출연한 celeb을 기준으로 
celeb 테이블과 snl_show 테이블을 self join 

select celeb.id, celeb.name, snl_show.id, snl_show.host
from celeb, snl_show
where celeb.name = snl_show.host;


#예제2
celeb 테이블의 연예인 중, snl_show에 host로 출연했고, 소속사가 안테나인 사람의 이름과 직업 검색

select celeb.name, celeb.job_title, celeb.agency, snl_show.host
from celeb, snl_show
where celeb.name = snl_show.host and agency='안테나';


#예제3
celeb 테이블의 연예인 중, snl_show에 host로 출연했고,
(영화배우는 아니면서 YG엔터테이먼트 소속이거나,
40세 이상이면서 YG엔터테이먼트 소속이 아닌) 연예인의
이름과 나이, 직업, 소속사, 시즌, 에피소드 정보를 검색

select celeb.name, celeb.age, celeb.agency, snl_show.season, snl_show.episode
from celeb, snl_show
where celeb.name = snl_show.host and 
((not job_title like '%영화배우%' and agency='YG엔터테이먼트') or 
(age>=40 and not agency='YG엔터테이먼트'));
snl_show에 출연한 연예인의 snl_show 아이디, 시즌, 에피소드, 이름, 직업 정보 검색

#컬럼명 앞에 테이블명 명시
select celeb.name, celeb.job_title, snl_show.id, snl_show.season, snl_show.episode
from celeb, snl_show
where celeb.name = snl_show.host;

#컬럼명만 명시(동일한 컬럼명에만 테이블명 명시)
select name, job_title, snl_show.id, season, episode
from celeb, snl_show
where celeb.name = snl_show.host;
#예제4
snl_show 시즌8에 출연한 celeb 중,
에피소드 7,9,10 중에 출연했거나
소속사가 YG로 시작하고 뒤에 6글자로 끝나는 사람 중 
20년 9월 15일 이후에 출연했던 사람 검색
select name, agency, season, episode, broadcast_date
from celeb, snl_show
where name = host
and (season=8 and episode in (7, 9, 10) or agency like 'YG______')
and broadcast_date > 20200915;

self join 문제

#문제1
snl_show에 출연한 celeb 테이블의 연예인 중, 영화배우나 탤런트가 아닌 연예인의 아이디, 이름, 직업, 시즌, 에피소드 정보를 검색

select celeb.id, celeb.name, job_title, season, episode
from celeb, snl_show
where name = host and
not (job_title like '%영화배우%' or job_title like '%탤런트%');

#영화배우나 탤런트가 아닌 -> or을 먼저 통과하고 not이 와야함


#문제2
snl_show에 출연한 celeb 중, 작년 9월 15일 이후에 출연했거나
소속사 이름이 '엔터테이먼트'로 끝나지 않으면서 영화배우나 개그맨이 아닌 연예인의 celeb 아이디, 이름, 직업, 소속사를 검색

select celeb.id, name, job_title, agency
from celeb, snl_show
where name = host
and (broadcast_date>20200915 or not agency like '%엔터테이먼트')
and not (job_title like '%영화배우%' or job_title like '%개그맨%');

0개의 댓글