일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 백준
- 백준 2293 자바
- 백준 2512 자바
- SQLD SQL 활용
- 백준 예산 자바
- 너비우선탐색
- SQLD 요약
- 자바 문자열 예제
- 알고리즘
- SQLD 내용 정리
- 백준 1141 접두사
- SQLD 내용
- 백준 동전1 자바
- 자바 이분 탐색 예제
- SQLD SQL 최적화 기본 원리
- SQLD 책
- 백준 2293 동전 1
- 백준 접두사 로직
- 백준 부분합 로직
- 자바 DP 예제
- BFS
- 백준 1141
- 백준 접두사 자바
- SQLD 정리
- 오라클 예제
- SQL 기본 및 활용
- 백준 1141 로직
- 자바 예제
- 백준 예산 코드
- SQLD
- Today
- Total
혼자 공부하는 공간
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 기본 #9 본문
<목차>
<< 조인 (JOIN) >>
* 지금까지는 하나의 테이블에서 데이터를 출력하는 것을 살펴보았다. 두 개 이상의 테이블들을 연결 또는 결합하여 데이터를 출력할 때 JOIN을 사용한다.
* 만약 A, B, C, D의 테이블이 조인될 때, 두 테이블을 조인 처리하고 그 결과와 또 다른 테이블을 조인 처리하는 식으로 두 개의 테이블만 조인 처리된다. (옵티마이저가 처리함.)
1. EQUI JOIN
* 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법.
* 대부분 PK와 FK의 관계를 기반으로 한다.
* 조인의 조건은 WHERE 절에 기술하는데 "=" 연산자를 사용해서 표현.
* 예시
1
2
3
4
5
6
7
8
9
10
11
12
|
/* 기본 형태 */
SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1, 테이블2
WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2;
/* WHERE 절에 JOIN 조건을 넣는다. */
/* ANSI/ISO SQL 표준 방식 */
SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1 INNER JOIN 테이블2
ON 테이블1.칼럼명1 = 테이블2.칼럼명2;
/* ON 절에 JOIN 조건을 넣는다. */
|
cs |
---> INNER JOIN 에서는 테이블의 순서가 결과에 영향을 미치지 않는다.
* 예시 - 문제
: 선수 테이블과 팀 테이블에서 선수 이름과 선수가 소속된 팀의 이름을 출력하시오.
* 예시 - 결과
1
2
3
4
5
6
7
8
|
SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명
FROM PLAYER, TEAM
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;
/* INNER JOIN을 명시하여 사용할 수도 있다. */
SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명
FROM PLAYER INNER JOIN TEAM
ON PLAYER.TEAM_ID = TEAM.TEAM_ID;
|
cs |
---> SELECT 절에 단순 칼럼명이 아닌 테이블명.칼럼명을 사용하는 이유
-
여러 테이블에서 칼럼명이 중복될 수도 있기 때문이다. 그렇게 되면 DBMS의 옵티마이저는 어떤 테이블의 칼럼을 사용해야 할지 모르기 때문에 에러가 발생한다.
-
SQL 문의 가독성에 도움 : 어느 테이블의 어떤 칼럼인지 바로 볼 수 있기 때문에.
-
향후 같은 칼럼이 생성되거나 하는 미래에 발생할 에러를 방지하는 효과.
1-1. 선수-팀 테이블 EQUI JOIN 사례
* 예시 - 문제
: 선수 테이블과 팀 테이블에서 K-리그 소속 선수들의 이름, 백넘버와 그 선수가 소속된 팀명과 연고지를 출력하라.
* 선수 테이블의 TEAM_ID(FK)와 팀 테이블에 있는 TEAM_ID(PK)의 관계를 통해 두 테이블을 재배열해서 알아보기 쉽게 만들 수 있다.
* 예시 - 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM.REGION_NAME
FROM PLAYER, TEAM
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;
/* INNER JOIN을 명시하여 사용할 수도 있다. */
SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM.REGION_NAME
FROM PLAYER INNER JOIN TEAM
ON PLAYER.TEAM_ID = TEAM.TEAM_ID;
/* SELECT 절이 길기 때문에 FROM 의 테이블에 ALIAS를 사용해서 SELECT을 줄일 수 있다. */
SELECT P.PLAYER_NAME, P.BACK_NO, P.TEAM_ID, T.TEAM_NAME, T.REGION_NAME
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID;
/*
PLAYER_NAME BACK_NO TEAM_ID TEAM_NAME REGION_NAME
----------- ------- ------- ------------ -----------
이고르 21 K06 아이파크 부산
오비나 26 K10 시티즌 대전
윤원일 45 K02 삼성블루윙즈 수원
페르난도 44 K04 유나이티드 인천
레오 45 K03 스틸러스 포항
실바 45 K07 드래곤즈 전남
무스타파 77 K04 유나이티드 인천
에디 7 K01 울산현대 울산
알리송 14 K01 울산현대 울산
쟈스민 33 K08 일화천마 성남
디디 8 K06 아이파크 부산
480개 항이 선택되었다.
*/
|
cs |
1-2. 선수-팀 테이블 WHERE 절 검색 조건 사례
* 위의 결과에서 WHERE 절에 추가적인 조건을 넣을 수 있다.
* 예시 - 문제
: 위의 조건에서 포지션이 'GK' 인 선수를 백넘버 순으로 정렬하여 출력하라.
* 예시 - 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
SELECT P.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID AND P.POSITION = 'GK'
ORDER BY P.BACK_NO;
/* INNER JOIN을 명시하여 사용할 수도 있다. */
SELECT P.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명
FROM PLAYER P INNER JOIN TEAM T
ON P.TEAM_ID = T.TEAM_ID
WHERE P.POSITION = 'GK'
ORDER BY P.BACK_NO;
/*
선수명 백넘버 연고지 팀명
------- ----- ----- ---------
최종문 1 전남 드래곤즈
정병지 1 포항 스틸러스
박유석 1 부산 아이파크
김승준 1 대전 시티즌
이현 1 인천 유나이티드
김운재 1 수원 삼성블루윙즈
정해운 1 성남 일화천마
권정혁 1 울산 울산현대
최동석 1 서울 FC서울
김창민 1 전북 현대모터스
김용발 18 전북 현대모터스
한동진 21 인천 유나이티드
이은성 21 대전 시티즌
김준호 21 포항 스틸러스
조범철 21 수원 삼성블루윙즈
....
43개 항이 선택되었다.
*/
|
cs |
---> JOIN의 조건을 기술할 때 FROM 절의 테이블이 ALIAS로 작성되었다며, SELECT나 WHERE 절에서도 ALIAS를 사용해야 한다.
1-3. 팀-운동장 테이블 EQUI JOIN 사례
* 예시 - 문제
: 소속팀이 가지는 운동장의 정보를 소속팀 정보와 함께 출력하라.
* 예시 - 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/* 기본 형태 */
SELECT TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME, STADIUM.SEAT_COUNT
FROM TEAM, STADIUM
WHERE TEAM.STADIUM_ID = STADIUM.STADIUM_ID;
/* INNER JOIN을 명시하여 사용할 수도 있다. */
SELECT TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME, STADIUM.SEAT_COUNT
FROM TEAM INNER JOIN STADIUM
ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID;
/* 테이블 ALIAS 사용 */
SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT
FROM TEAM T, STADIUM S
WHERE T.STADIUM_ID = S.STADIUM_ID;
/* INNER JOIN ALIAS 사용 */
SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT
FROM TEAM T INNER JOIN STADIUM S
ON T.STADIUM_ID = S.STADIUM_ID;
/*
REGION_NAME TEAM_NAME STADIUM_ID STADIUM_NAME SEAT_COUNT
----------- ----------- ---------- -------------- ----------
전북 현대모터스 D03 전주월드컵경기장 28000
성남 일화천마 B02 성남종합운동장 27000
포항 스틸러스 C06 포항스틸야드 25000
전남 드래곤즈 D01 광양전용경기장 20009
서울 FC 서울 B05 서울월드컵경기장 66806
........
15개의 행이 선택되었다.
*/
|
cs |
2. Non EQUI JOIN
* Non EQUI JOIN(비등가) JONI은 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 사용된다.
* "=" 연산자가 아닌 BETWEEN, >, >=, <, <= 등과 같은 연산자들을 사용하여 JOIN을 수행한다.
* 참조 테이블
* 예시 - 문제
: 사원 모두에 대해서 급여와 급여에 해당하는 급여 등급을 출력하라.
* 예시 - 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
SELECT E.ENAME 사원명, E.SAL 급여, S.GRADE 급여등급
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;
/*
사원명 급여 급여등급
------ ---- ------
SMITH 800 1
JAMES 950 1
ADAMS 1100 1
WARD 1250 2
MARTIN 1250 2
MILLER 1300 2
TURNER 1500 3
ALLEN 1600 3
CLARK 2450 4
BLAKE 2850 4
JONES 2975 4
SCOTT 3000 4
FORD 3000 4
KING 5000 5
14개의 행이 선택되었다.
*/
|
cs |
---> 데이터 모델에 따라서 Non EQUI JOIN이 불가능한 경우도 존재한다.
3. 3개 이상의 TABLE JOIN
* 예시 - 문제
: 선수들 별로 홈그라운드 경기장 정보를 출력하라
---> 선수 테이블과 운동장 테이블은 상관관계가 없으므로 중간에 팀 테이블이라는 상관관계가 있는 테이블을 추가해서 3개의 테이블을 JOIN 해야한다.
---> 선수 테이블의 TEAM_ID가 팀 테이블의 TEAM_ID와 PK-FK의 상관관계에 있고, 운동장 테이블의 STADIUM_ID와 팀 테이블의 STADIUM_ID가 PK-FK 상관관계에 있다는 것을 이용.
(WHERE 절에 2개 이상의 JOIN 조건이 필요하다.)
* 예시 - 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/* 기본 형태 */
SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지, T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P, TEAM T, STADIUM S
WHERE P.TEAM_ID = T.TEAM_ID AND T.STADIUM_ID = S.STADIUM_ID
ORDER BY 선수명;
/* INNER JOIN 명시 */
SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지, T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P INNER JOIN TEAM T
ON P.TEAM_ID = T.TEAM_ID INNER JOIN STADIUM S
ON T.STADIUM_ID = S.STADIUM_ID
ORDER BY 선수명;
/*
선수명 포지션 연고지 팀명 구장명
-------- ----- ----- ------------ -------------
가비 MF 수원 삼성블루윙즈 수원월드컵경기장
가이모토 DF 성남 일화천마 성남종합운동장
강대희 MF 수원 삼성블루윙즈 수원월드컵경기장
강성일 GK 대전 시티즌 대전월드컵경기장
강용 DF 포항 스틸러스 포항스틸야드
강정훈 MF 대전 시티즌 대전월드컵경기장
......
480개의 행이 선택되었다.
*/
|
cs |
* JOIN의 필요성
: 정규화는 불필요한 데이터의 중복을 줄이고, 데이터의 정합성을 유지하여 이상현상을 방지하는 모델링 기법이다. 그 결과로 테이블을 분할하기 때문에 여러 테이블의 데이터를 핸들링하기 위해서는 JOIN이 필수적이다.
* JOIN을 사용하지 않으면?
: 하나의 테이블에 모든 데이터를 집중시키면 JOIN에 대한 비용은 없지만, 가장 중요한 데이터 정합성 유지에 더 많은 비용이 들어가게 된다.
: 한 테이블에 데이터가 집중되는 경우, 방대한 데이터에서 검색하는 속도 자체가 떨어질 수도 있다.
: JOIN은 비용에 대한 리스크가 존재하기 때문에 신중하게 작성해야 한다.
출처
질문은 댓글로 남겨주시면 되겠습니다. 감사합니다.
'자격증 > SQLD' 카테고리의 다른 글
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 활용 #2 (0) | 2020.08.27 |
---|---|
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 활용 #1 (0) | 2020.08.27 |
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 기본 #8 (0) | 2020.08.22 |
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 기본 #7 (0) | 2020.08.22 |
[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 기본 #6 (0) | 2020.08.21 |