먼저 예제로 사용할 테이블의 구조를 살펴보자.
SQL> SELECT * FROM 과목; 과목 과목이름 학점 학과 담당교수 ---- --------------- ---------- --------------- ---------- C123 프로그래밍 3 컴퓨터 김성국 C312 자료구조 2 컴퓨터 황수관 C324 파일처리 3 멀티 이규찬 C413 데이터베이스 3 통신 지정은 E412 반도체 2 전자 홍봉진 C824 인간관계론 3 경영 D150 정보통신 3 멀티 7 개의 행이 선택되었습니다. SQL> SELECT * FROM 학생; 학번 이름 학년 학과 ---------- ---------- ---------- --------------- 100 나수영 4 컴퓨터 200 이찬수 3 컴퓨터 300 정기태 1 컴퓨터 400 송병길 4 경영 500 박종화 2 컴퓨터 600 안재하 1 전자공학 6 개의 행이 선택되었습니다. SQL> SELECT * FROM 등록; 학번 과목 중간성적 기말성적 ---------- ---- - ---------- ---------- 100 C413 A 90 95 100 E412 A 95 95 200 C123 B 85 80 300 C312 A 90 95 300 C324 D 75 75 300 C413 A 95 90 400 C312 A 90 95 400 C324 A 95 90 400 C413 B 80 85 400 E412 D 65 75 500 C312 F 50 40 600 C413 A 95 95 12 개의 행이 선택되었습니다.
컴퓨터과 과목을 적어도 한 과목 등록한 학생의 모든 이름을 구해보자.
한번에 쿼리로는 불가능하고 테이블을 JOIN 후 서브쿼리 등을 활용해 구해야 한다.
SQL> SELECT 이름 FROM 학생 NATURAL JOIN 등록 WHERE 과목번호 IN (SELECT 과목번호 FROM 과목 WHERE 학과='컴퓨터'); 이름 ---------- 박종화 정기태 이찬수 송병길 SQL> SELECT 학생.이름 FROM 학생, 등록, 과목 WHERE (학생.학번 = 등록.학번) AND (등록.과목번호 = 과목.과목번호) AND 과목.학과='컴퓨터'; 이름 ---------- 이찬수 정기태 송병길 박종화
두가지 모두 같은 결과를 가져온다.
세 개의 테이블 모두를 연결해야하고 그 중에서 컴퓨터 과목에 해당하는 수강 번호를 등록한 학생들만 가져오게 된다.
해석을 해보자.
SELECT
결국 원하는 것은 학생의 이름이다. 따라서 SELECT 다음의 필드명은 이름이 오게된다.
FROM
이름과 과목번호, 학번 등이 연동되므로 등록과 학생 테이블만 사용된다. 따라서 이 둘을 NATURAL JOIN 해주는 것이 편리하다.
WHERE
이제 처음 구하려고 했던 이름에 대한 제한조건을 걸 필요가 있다.
WHERE 절을 사용해서 과목번호가 컴퓨터과의 과목과 일치하면 우리가 원하는 인스턴스일 것이다.
서브쿼리
그런데 컴퓨터과의 과목은 하나가 아니므로 = (같다) 가 아닌 IN 을 사용해서 처리하는 것이 좋다.
따라서 서브쿼리를 활용해서 학과가 컴퓨터인 과목번호들을 가져와서 IN 과 붙여주면 완료된다.
이번에는
학번이 100인 학생이 등록한 과목에 적어도 한과목을 같이 등록한 학생의 이름을 찾아보자.
SQL> SELECT DISTINCT 이름 FROM 학생 NATURAL JOIN 등록 WHERE 과목번호 IN (SELECT 과목번호 FROM 등록 WHERE 학번=100) AND 학번 != 100; 이름 ---------- 정기태 안재하 송병길
이번에는 모든 과목에 등록한 학생의 이름을 전부 가져와 보자.
위의 테이블을 살펴볼 때 그러한 학생은 없으므로 결과는 아무도 없어야 한다.
SQL> SELECT DISTINCT 이름 FROM 학생 NATURAL JOIN 등록 WHERE 과목번호 = ALL ( SELECT 과목번호 FROM 과목 ); 선택된 레코드가 없습니다.