데이터 조회 |
조인
조인은 두 개의 테이블로부터 연관된 레코드들을 결합한다. 조인의 일반적인 형식은 FROM 절에 두 개 이상의 테이블들이 열거되고, 두 테이블에 속하는 컬럼들을 비교하는 조인 조건이 WHERE 절에 포함된다.
카티션 곱(Cartesian Product)
예제 48 |
√ 문제
NATION 테이블과 CODE 테이블의 카티션 곱을 조회하라.
√ SQL문 1
|
SELECT *
FROM NATION, CODE
혹은
SELECT *
FROM NATION CROSS JOIN CODE |
|
√ SQL문 2
|
SELECT COUNT(*) FROM NATION
SELECT COUNT(*) FROM CODE
SELECT COUNT(*) FROM NATION, CODE |
|
√ 결과 1
|
NO |
CODE |
NAME |
CONTINENT |
CAPITAL |
S_NAME |
F_NAME |
1 |
SRB |
Serbia |
Europe |
Beograd |
X |
Mixed |
2 |
SRB |
Serbia |
Europe |
Beograd |
W |
Woman |
3 |
SRB |
Serbia |
Europe |
Beograd |
M |
Man |
4 |
SRB |
Serbia |
Europe |
Beograd |
B |
Bronze |
5 |
SRB |
Serbia |
Europe |
Beograd |
S |
Silver |
|
√ 결과 2
|
NO |
COUNT(*) |
1 |
215 |
1 |
6 |
1 |
1290 |
|
√ 설명
카티션 곱은 가능한 모든 행들의 조합을 만든다. NATION 테이블의 레코드가 215개, CODE 테이블의 레코드가 6개 이면 두 테이블의 조합인 카티션 곱의 레코드 수는 215 * 6 = 1290개가 된다. |
세타 조인과 동등 조인
세타 조인의 결과는 조인 조건을 만족하는 레코드들로 이루어진 테이블이다. 세타 조인을 수행하기 위해서 양쪽 테이블의 컬럼이 세타 조인 조건을 만족하는 레코드만 골라낸다. 세타는 [=, <>, <=, <. , >] 중 하나이며 동등 조인은 이 중에서 비교 연산자가 ‘=’인 조인이다.
예제 48 |
√ 문제
NATION 테이블과 STADIUM 테이블을 조인하여 Nation_Name(국가명), Capital_Name(수도명), Stadium_Name(경기장명)을 출력하는 쿼리 문을 작성하라.
√ SQL문
|
SELECT N.NAME AS "Nation_Name",
N.CAPITAL AS "Capital_Name",
S.NAME AS "Stadium_Name"
FROM STADIUM AS S, NATION AS N
WHERE S.NATION_CODE = N.CODE |
|
√ 결과
|
NO |
Nation_Name |
Capital_Name |
Stadium_Name |
44 |
Australia |
Canberra |
Pavilion |
45 |
Korea |
Seoul |
Modern |
46 |
Korea |
Seoul |
Royal |
47 |
Korea |
Seoul |
Changchung |
48 |
Korea |
Seoul |
Saemaul |
|
√ 설명
두 개의 테이블을 조인할 때 N이나 S와 같은 ALIAS를 사용하면 보다 간단하게 사용할 수 있다. |
외부 조인(outer join)
예제 49 |
√ 문제
NATION 테이블과 STADIUM 테이블을 조인하여 Nation_Name(국가명), Capital_Name(수도명), Stadium_Name(경기장명)을 출력하는 쿼리 문을 작성하라.
√ SQL문
|
SELECT N.NAME, O.MASCOT
FROM NATION AS N, OLYMPIC AS O
WHERE N.NAME = O.HOST_NATION(+)
혹은
SELECT N.NAME, O.MASCOT
FROM NATION AS N LEFT OUTER JOIN OLYMPIC AS O ON N.NAME = O.HOST_NATION |
|
√ 결과
|
NO |
Nation_Name |
Capital_Name |
9 |
Argentina |
(NULL) |
10 |
Armenia |
(NULL) |
11 |
Aruba |
(NULL) |
12 |
Australia |
Olly |
13 |
Australia |
(NULL) |
219 |
kenya |
(NULL) |
|
√ 설명
외부 조인은 조인 조건의 양쪽 컬럼 중 하나가 NULL인 경우도 결과 테이블에 나타낼 때 사용한다. 외부 조인을 사용하려면 WHERE절에서 (+) 기호를 사용하거나 OUTER JOIN절을 사용하면 되고 만약에 LEFT인지 RIGHT인지 구분하고자 한다면 널 값이 있는 곳에 (+) 기호를 두고 사용하며 된다. 그리고 현재 큐브리드에서는 FULL OUTER JOIN은 지원하지 않는다. |
자체 조인(self join)
예제 49 |
√ 문제
NATION 테이블에서 NATION_NAME(국가명)과 CAPITAL(수도명)이 같은 쿼리를 출력하게 하라.
√ SQL문
|
SELECT B.CODE, A.NAME, B.CAPITAL
FROM NATION AS A, NATION AS B
WHERE A.NAME = B.CAPITAL |
|
√ 결과
|
NO |
Nation_Name |
Capital_Name |
1 |
DJI |
Djibouti |
2 |
LUX |
Luxembourg |
3 |
MON |
Monaco |
4 |
SMR |
San |
5 |
SIN |
Singapore |
|
√ 설명
한 테이블에 속하는 레코드를 동일한 테이블에 속하는 레코드와 조인하는 것을 자체 조인이라 한다. 실제로는 한 테이블이 접근되지만 FROM 절에서 두 테이블이 참조 되는 것처럼 하기 위해 각각의 테이블에 대해 ALIAS를 지정해야 한다. |
조인과 ORDER BY의 결합
예제 50 |
√ 문제
NATION 테이블과 STADIUM 테이블을 조인하여 Nation_Name(국가명), Capital_Name(수도명), Stadium_Name(경기장명)을 출력하는 쿼리 문을 작성하라.
√ SQL문
|
SELECT N.NAME AS "Nation_Name",
N.CAPITAL AS "Capital_Name",
S.NAME AS "Stadium_Name"
FROM STADIUM AS S, NATION AS N
WHERE S.NATION_CODE = N.CODE
ORDER BY Stadium_Name, Nation_Name DESC |
|
√ 결과
|
NO |
Nation_Name |
Capital_Name |
Stadium_Name |
1 |
Spain |
Madrid |
A-17 |
16 |
United |
States |
of |
17 |
Greece |
Athens |
Ano |
18 |
Greece |
Athens |
Ano |
19 |
Greece |
Athens |
Athens |
|
√ 설명
Stadium_Name을 오름차순으로 정렬한 후, Capital_Name을 내림차순으로 정렬한다. |
세 개 이상의 테이블 조인
예제 51 |
√ 문제
한국 국적의 선수들의 성별, 스포츠 종목과 획득 메달을 출력하는 쿼리를 작성하라.
√ SQL문
|
SELECT A_NATION_CODE, A.NAME, E.GENDER, E.SPORTS, R.MEDAL
FROM EVENT AS E, ATHLETE AS A, RECORD AS R
WHERE E.CODE=R.EVENT_CODE AND
A.CODE=R.ATHLETE_CODE AND A.NATION_CODE='KOR' |
|
√ 결과
|
NO |
Nation_Code |
NAME |
GENDER |
SPORTS |
MEDAL |
1 |
KOR |
Chun |
Byung-Kwan |
M |
Weightlifting |
2 |
KOR |
Kang |
Cho-Hyun |
W |
Shooting |
3 |
KOR |
Hwang |
Young-Cho |
M |
Athletics |
4 |
KOR |
Lee |
Eun-Chul |
M |
Shooting |
5 |
KOR |
Lee |
Bong-Ju |
M |
Athletics |
|
√ 설명
세 개의 테이블을 조인할 때에는 두 개의 조인 조건식을 AND로 연결한다. |
|
|
중첩 질의
일부 질의들은 데이터베이스에서 어떤 값들을 검색한 후에 이를 비교 조건에서 사용한다. 이런 질의들은 중첩 질의를 사용해서 편리하게 표현할 수 있다. 중첩 질의는 외부 질의의 WHERE절에 포함되는 SELECT문을 말하며 부 질의(Sub_Query)라고 한다.
한 개의 스칼라 값이 반환되는 경우
예제 52 |
√ 문제
Park Jae-Hong과 같은 국가인 모든 선수들의 이름과 종목을 조회하라.
√ SQL문 1
|
SELECT NAME, NATION_CODE, EVENT
FROM ATHLETE
WHERE NAME='Park Jae-Hong' |
|
√ SQL문 2
|
SELECT NAME, NATION_CODE, EVENT
FROM ATHLETE
WHERE NATION_CODE = 'KOR' |
|
√ SQL문 3
|
SELECT NAME, NATION_CODE, EVENT
FROM ATHLETE
WHERE NATION_CODE =
(SELECT NATION_CODE FROM ATHLETE WHERE NAME='Park Jae-Hong') |
|
√ 결과 1
|
NO |
NAME |
NATION_CODE |
EVENT |
1 |
Park |
Jae-Hong |
KOR |
|
√ 결과 2
|
NO |
NAME |
NATION_CODE |
EVENT |
1 |
Chung |
So-Young |
KOR |
2 |
Chung |
Min-Tae |
KOR |
3 |
Chung |
Jae-Hun |
KOR |
4 |
Chung |
Hoon |
KOR |
5 |
Chun |
Byung-Kwan |
KOR |
6 |
Chong |
Tae-Hyon |
KOR |
7 |
Choi |
Mi-Soon |
KOR |
|
√ 결과 3
|
NO |
NAME |
NATION_CODE |
EVENT |
1 |
Chung |
So-Young |
KOR |
2 |
Chung |
Min-Tae |
KOR |
3 |
Chung |
Jae-Hun |
KOR |
4 |
Chung |
Hoon |
KOR |
5 |
Chun |
Byung-Kwan |
KOR |
6 |
Chong |
Tae-Hyon |
KOR |
7 |
Choi |
Mi-Soon |
KOR |
|
√ 설명
2번과 3번의 실행 결과는 같다. |
한 개의 컬럼으로 이루어진 테이블이 반환되는 경우
중첩 질의의 결과로 한 개의 컬럼으로 이루어진 다수의 레코드들이 반환될 수 있다. 외부 질의의 WHERE절에서 IN, ANY(SOME), ALL, EXISTS와 같은 연산자를 사용해야 한다. 키워드 IN은 한 컬럼이 값들의 집합에 속하는가를 테스트할 때 사용한다. 만일 한 컬럼이 값들의 집합에 속하는 하나 이상의 값들과 어떤 관계를 갖는가를 테스트 하는 경우에는 ANY를 사용하고, 만일 한 컬럼이 값들의 집합에 속하는 모든 값들과 어떤 관계를 갖는가를 테스트하는 경우에는 ALL을 사용한다.
예제 53 |
√ 문제
NATION 테이블의 NATION_CODE가 KOR 또는 USA인 STADIUM 테이블의 NATION_CODE와 NAME을 출력하는 쿼리문을 작성하라.
√ SQL문
|
SELECT NATION_CODE, NAME
FROM STADIUM
WHERE NATION_CODE
IN (SELECT NATION_CODE FROM NATION WHERE NATION_CODE IN ('KOR', 'USA')) |
|
√ 결과
|
NO |
NATION_CODE |
NAME |
16 |
USA |
Clark-Atlanta-University |
17 |
USA |
Atlanta-Fulton-Country-Stadium |
18 |
USA |
Atlanta-Beach |
19 |
USA |
Alexander-Memorial-Coliseum |
20 |
KOR |
Modern-Pentathlon-Stadium |
21 |
KOR |
Royal-Bowling-Center |
|
|
여러 컬럼으로 이루어진 테이블이 반환되는 경우
중첩 질의의 결과로 여러 컬럼들로 이루어진 테이블이 반환되는 경우에는 EXISTS 연산자를 사용하여 중첩 질의의 결과가 빈 테이블인지 여부를 검사한다. 중첩 질의의 결과가 빈 테이블이 아니면 참이 되고, 그렇지 않으면 거짓이 된다. NOT EXISTS는 EXISTS의 반대로 테스트 한다고 생각하면 된다.
예제 54 |
√ 문제
NATION 테이블의 NATION_CODE가 KOR 또는 USA인 STADIUM 테이블의 NATION_CODE와 NAME을 출력하는 쿼리문을 작성하라.
√ SQL문
|
SELECT NATION_CODE, NAME
FROM STADIUM
WHERE EXISTS
(SELECT NATION_CODE FROM NATION WHERE NATION_CODE IN ('KOR', 'USA')) |
|
√ 결과
|
NO |
NATION_CODE |
NAME |
16 |
USA |
Clark-Atlanta-University |
17 |
USA |
Atlanta-Fulton-Country-Stadium |
18 |
USA |
Atlanta-Beach |
19 |
USA |
Alexander-Memorial-Coliseum |
20 |
KOR |
Modern-Pentathlon-Stadium |
21 |
KOR |
Royal-Bowling-Center |
|
|
상관 중첩 질의(correlated nested query)
중첩 질의의 WHERE절에서 외부 질의에 선언된 테이블의 일부 컬럼을 참조하는 질의를 상관 중첩 질의라 한다. 상관 중첩 질의는 외부 질의를 만족하는 각 레코드가 구해진 후 중첩 질의가 수행된다. 따라서 상관 중첩 질의는 외부 질의를 만족하는 레코드 수만큼 여러 번 수행할 수 있다.
예제 55 |
√ 문제
PARTICIPANT 테이블에서 GOLD(금메달) 획득 수가 평균 이상인 NATION_CODE(국가 코드)와 GOLD(금메달 수)를 출력하는 쿼리 문을 작성하라.
√ SQL문
|
SELECT NATION_CODE, GOLD
FROM PARTICIPANT
WHERE GOLD >= (SELECT AVG(GOLD) FROM PARTICIPANT) |
|
√ 결과
|
NO |
NATION_CODE |
GOLD |
1 |
CHI |
2 |
2 |
ARG |
2 |
3 |
DEN |
2 |
4 |
MAR |
2 |
27 |
HUN |
8 |
36 |
AUS |
17 |
37 |
RUS |
27 |
38 |
CHN |
32 |
|
√ 설명
동일한 테이블 안에서 중첩하여 질의를 사용함으로써 컬럼의 값을 비교하여 해당되는 값을 출력할 수 있다. |
|
|
FROM절에 내포된 질의
FROM절에 열거하는 테이블을 내포된 질의로 표현할 수 있다. WHERE절의 조건식에 관계 연산자로 길게 표현되면 질의를 이해하기 어려울 수 있다. 이런 경우에는 FROM절에서 먼저 조건문을 적용하고, 그 결과 테이블을 조인하면 이해하기가 쉬워진다. 한 SELECT문의 FROM절에 내포된 SELECT문을 인라인 뷰(inline view)라고도 한다.
예제 56 |
√ 문제
NATION 테이블과 ATHLETE 테이블에서 종목 명(EVENT)이 Taekwondo인 쿼리를 작성하라. (출력 컬럼 : 대륙 명(CONTINENT), 나라 명(NATION_NAME), 선수 명(NAME), 종목 명(EVENT))
√ SQL문
|
SELECT N.CONTINENT, N.NAME, A.NAME, A.EVENT FROM NATION N,
(SELECT NATION_CODE, NAME, EVENT FROM ATHLETE) AS A
WHERE N.CODE = A.NATION_CODE AND A.EVENT='Taekwondo' |
|
√ 결과
|
NO |
CONTINENT |
NATION_CODE |
NAME |
EVENT |
25 |
Americas |
Cuba |
Labrada_Diaz_Yy |
Taekwondo |
26 |
Asia |
Iran |
Karami_Yossef |
Taekwondo |
27 |
Asia |
Korea |
Jang_Ji_Won |
Taekwondo |
28 |
Asia |
Korea |
Hwang_yung_Sun |
Taekwondo |
29 |
Asia |
Taiwan |
Huang_Chih_Hsiung |
Taekwondo |
30 |
Asia |
Taiwan |
Chu_Mu_Yen |
Taekwondo |
31 |
Asia |
Taiwan |
Chen_Shih_Hsin |
Taekwondo |
|
|
예제 57 |
√ 문제
CONTINENT가 Asia인 NATION_NAME과 STADIUM_NAME을 출력하는 쿼리 문을 작성하라.
√ SQL문
|
SELECT N.NAME AS NATION_NAME, S.NAME AS STADIUM_NAME FROM
(SELECT CODE, NAME, CONTINENT FROM NATION) AS N,
(SELECT NATION_CODE, NAME FROM STADIUM) AS S
WHERE N.CODE=S.NATION_CODE AND N.CONTINENT = 'Asia' |
|
√ 결과
|
NO |
NATION_NAME |
STADIUM_NAME |
1 |
Korea |
1 |
2 |
Korea |
2 |
3 |
Korea |
3 |
4 |
Korea |
4 |
5 |
Korea |
5 |
6 |
Korea |
6 |
7 |
Korea |
7 |
|
|
|
|