Infra & Security Eng/Database Engineering

등가조인, 비등가조인 개념과 사용하는 이유, 예시, 실습

엔지니어 E 2026. 1. 29. 14:05
반응형

등가조인 개념과 등가조인을 쓰는 이유 

SELECT 테이블.컬럼, ……
FROM 테이블, 테이블, ......
WHERE 조인_조건
AND 일반_조건 ORDER BY 컬럼 ......;

개념: 두 테이블에서 값이 정확히 일치(=) 하는 데이터들만 골라서 합치는 가장 기본적인 조인 방식

사용하는 이유: 데이터베이스를 설계할 때, 보통 중복을 피하기 위해 데이터를 쪼개서 저장함. 예를 들어 모든 사원 정보 옆에 '부서명'과 '근무지'를 일일이 다 적으면 데이터 용량이 낭비되므로 '사원 테이블(emp)'에는 부서 번호만 적어두고, 상세한 '부서 정보(dept)'는 따로 관리함

SQL> SELECT d.dno, dname, eno, ename, sal, sal*1.1, grade 2 FROM dept d, emp e, salgrade s 3 WHERE d.dno = e.dno AND sal*1.1 BETWEEN losal AND hisal 4 AND dname = '총무';
테이블이 3개 이므로 테이블 3개의 관계를 다 적어줘야 함
 

등가조인 예시

각 사원의 근무 부서와 근무지를 검색함 

1. 테이블 전체 이름을 사용한 등가 조인 
SQL> SELECT dept.dno 부서번호, dname 부서, loc 근무처, ---> dept 테이블의 dno, dname, loc 정보를 가져오고 
* emp.dno 부서번호로 써도 된다. 하지만 원조 데이터는 detp 이므로 원조 테이블로 많이 씀

2 eno 사번, ename 이름 ---> emp 테이블의 eno와 ename 정보를 가져온다 
3 FROM dept, emp ---> 사용할 데이터는 dept와 emp 두 군데에 있다
4 WHERE dept.dno=emp.dno; ---> 단, 두 테이블의 부서번호(dno)가 똑같은 데이터만 합친다

2. 별명으로 줄여쓴 등가 조인 -* 실무에서 더 많이 사용 
SQL> SELECT d.dno 부서번호, dname 부서, loc 근무처, ---> d(dept)의 dno와 나머지 부서 정보를 선택하고
2 eno 사번, ename 이름 ---> e(emp)의 사번과 이름 정보를 선택
3 FROM dept d, emp e ---> dept는 앞으로 'd'로, emp는 'e'로 부르겠다고 선언
4 WHERE d.dno=e.dno; ---> d의 부서번호와 e의 부서번호가 같은 것끼리 짝을 짓는다
* 별명이 부여된 경우 테이블명은 사용할 수 없음

💡참고사항

등가 조인 쓸 때 FROM dept, emp 를 썼다면 
where dept.dno=emp.dno 를 쓴다 당연히 써주는 것
from student, course 는 관계 존재하지 않으므로 from student,course, score를 같이 써서 관계를 이어준다 

1 select sno, sname, cname, grade 검색한다
from student s,c course c , scgrade d 
2. 조건은 cname ='일반화학' AND grade='A'
3. 이제 관계를 살펴보면 됨 여기에 score가 들어가면 관계가 들어가게 된다 
조건은 From student s,score R, c course c , scgrade d * score R 은 넣는다 
sno 테이블에 들어 있는게 공통 되므로 s.sno 를 넣어준다 
AND s.sno=r , sno AND c.cno=r.cno aAND result BETWEEN loscore AND hiscore; ---> 다시 정리 

비등가 조인 개념과 비등가 조인을 쓰는 이유 

개념: 똑같은 값이 없어도, 특정 범위(BETWEEN)에 속하면 데이터를 연결하는 방식으로 조인 조건에 = (이퀄) 연산자가 아닌 BETWEEN, >, <, >= 등의 연산자를 사용하여 테이블을 합치는 방식

사용 하는 이유: 실무 데이터는 딱 떨어지는 번호뿐만 아니라 범위 에 속해야 하는 경우가 많다. 예를 들어, 사원의 급여가 3,000원일 때 "3,000원급"이라는 등급은 없지만 **"2,500원 ~ 3,500원 사이(범위)"**에 속한다면 그 등급을 가져와야 하기 때문

 

비등가조인 예시

SQL> SELECT eno, ename, sal, grade ---> e(emp)의 이름, 급여와 s(salgrade)의 등급 정보를 선택
---> 순서가 이런 이유는 누가 어떤 등급인지가 중요하나거지 어떤 등급에 사람이 있는지가 중요한게 아니기 때문, 데이터는 순서대로 옴, 어떤 데이터가 중요하냐에 다라 잘 생각해서 배치한다 
2 FROM emp e, salgrade s ---> emp는 'e'로, salgrade는 's'로 부르겠다고 선언
3 WHERE sal BETWEEN losal AND hisal; ---> e의 급여가 s의 최소~최대 범위 안에 있으면 짝을 짓는다

 

등가조인+비등가조인 예시

총무 부서 사원의 급여를 10% 인상한 겨우 사원의 급여등급을 검색함

SQL> SELECT d.dno(원래 dept.dno), dname, eno, ename, sal, sal*1.1, grade ---> 
* d.dno, dname 을 적은 이유는 eno, ename, sal, sal*1.1, grade 만 적으면 부서와 사원테이블에는 사번, 이름, 급여는 있지만 부서명은 없기 때문에 등가조인을 해야한다
* 총무 부서'**라는 조건을 줬으므로, 부서 정보의 원천인 dept(d) 테이블의 번호를 기준으로 삼아 출력하는 것이 가장 논리적임
2 FROM dept d, emp e, salgrade s ---> 부서(d), 사원(e), 등급(s) 테이블 3개를 모두 각져와서
3 WHERE d.dno = e.dno(등가조인) ---> 부서번호가 같은 사원과 부서를 1:1 을 매칭
4 AND sal*1.1 BETWEEN losal AND hisal(비등가조인) ---> 사원의 인상된 급여(sal*1.1)가 등급표의 최소~ 최대 번위 안에 있으면 그 등급을 가져와서 합쳐
5 AND dname = '총무';(일반조건) ---> 그 중 부서 이름이 총무'인 사람만 남기고 나머지는 다 버려

1. 송강 교수가 강의하는 과목을 검색한다.
SELECT professor.pname 교수명, profassor.pno 교수번호 course.cname 과목명
FROM professor, course
WHERE professor.pno = course.pno
AND professor.pname = '송강';

2. 과목명에 화학이 포함된 과목을 강의하는 교수의 명단을 검색한다.
SELECT course.cname 과목명, professor.pname 교수명,  profassor.pno 교수번호 ---> 데이터 추출 시 반드시 어느 데이터를 가져올지를 첫번째로 생각한다
과목명에 ~
FROM course, professor
WHERE course.pno = professor.pno
AND course.cname LIKE '%화학%';

3. 학점이 2학점인 과목과 이를 강의하는 교수를 검색한다.
SELECT course.cname 과목명, course.st_num 학점, professor.pname 교수명,  profassor.pno 교수번호
FROM course, professor
WHERE course.pno = professor.pno
AND course.st_num = 2;


4. 화학과 교수가 강의하는 과목을 검색한다.
SELECT professor.section 소속학과, professor.pname 교수명,  profassor.pno 교수번호, course.cname 과목명
FROM professor, course
WHERE professor.pno = course.pno
AND professor.section = '화학';

5. 화학과 1학년 학생의 기말고사 성적을 검색한다.
SELECT student.sno 학번, student.sname 이름, student.major 학과, student.syear 학년, score.result 점수
FROM student, score
WHERE student.sno = score.sno
AND student.major = '화학' AND student.syear = 1;


6. 일반화학 과목의 기말고사 점수를 검색한다.
SELECT course.cname 과목명, score.result 점수
FROM course, score
WHERE course.cno = score.cno
AND course.cname = '일반화학';

7. 화학과 1학년 학생의 일반화학 기말 고사 점수를 검색한다.
SELECT student.major 학과, student.sno 학번 , student.sname 이름, course.cname 과목명, score.result 점수
FROM student, score, course
WHERE student.sno = score.sno
AND score.cno = course.cno
AND student.major = '화학' AND student.syear = 1
AND course.cname = '일반화학';

8. 화학과 1학년 학생이 수강하는 과목을 검색한다.
SELECT DISTINCT course.cname 과목명 - 과목만 검색을 하는 것이므로 course.cname만 입력, DISTINCT 입력을 안하면 과목만 만 나오는게 아니라 화학과, 1학년이 테이블도 계속 같이 나오므로 
FROM student, score, course
WHERE student.sno = score.sno
AND score.cno = course.cno
AND student.major = '화학'
AND student.syear = 1;


9. 일반화학 과목에서 평가 점수가 A인 학생의 명단을 검색한다.
SELECT student.sname 이름, student.sno 학번, course.cname 과목명, score.result 점수, scgrade.grade 등급
FROM student, score, course, scgrade
WHERE student.sno = score.sno
AND score.cno = course.cno
AND score.result BETWEEN scgrade.loscore AND scgrade.hiscore
AND course.cname = '일반화학' AND scgrade.grade = 'A';


10. 송강 교수의 과목을 수강하는 학생의 기말고사 점수를 성적 순서로 검색한다.
SELECT professor.pno 교수번호 professor.pname 교수명, course.cname 과목명, student.sname 학생명, student.sno 학번, score.result 점수
FROM professor, course, score, student
WHERE professor.pno = course.pno
AND course.cno = score.cno
AND score.sno = student.sno
* professor.pno = course.pno: 교수와 과목을 교수번호로 연결
course.cno = score.cno: 과목과 점수를 과목번호로 연결
score.sno = student.sno: 점수와 학생을 학번으로 연결
AND professor.pname = '송강'
ORDER BY score.result DESC;

11. 화학과 1학년 학생의 기말고사 성적을 학점(A,B,C,D,F)으로 검색한다.
SELECT student.major 학과, student.syear 학년, student.sname 이름, student.sno 학번, score.result 점수, scgrade.grade 학점
FROM student, score, scgrade
WHERE student.sno = score.sno
AND score.result
BETWEEN scgrade.loscore AND scgrade.hiscore
AND student.major = '화학'
AND student.syear = 1;

12. 송강 교수가 강의하는 과목에서 평가 점수가 A인 학생의 명단을 과목명과 함께 검색한다
SELECT course.cname 과목명, student.sno 학번, student.sname 이름, professor.pname 교수명 scgrade.grade 등급
FROM professor, course, score, student, scgrade
WHERE professor.pno = course.pno AND course.cno = score.cno AND score.sno = student.sno AND score.result BETWEEN scgrade.loscore AND scgrade.hiscore
AND professor.pname = '송강'
AND scgrade.grade = 'A';

13. 화학과 1학년 학생에게 강의하는 교수의 명단을 검색한다
SELECT DISTINCT professor.pname 교수명, professor.pno 교수번호
FROM student, score, course, professor
WHERE student.sno = score.sno AND score.cno = course.cno AND course.pno = professor.pno AND student.major = '화학' AND student.syear = 1;

*student.sno = score.sno: 학생과 성적을 연결
score.cno = course.cno: 성적과 과목을 연결
course.pno = professor.pno: 과목과 교수를 연결
이렇게 테이블 4개가 줄줄이 사탕처럼 엮여야 '화학과 1학년'과 '교수님' 사이의 접점이 생긴다