2019. 12. 5. 09:42ㆍSecurity/sql
* 모델링
일반 컬럼들이 프라이머리 키 컬럼에 함수적 종속관계에 있음.
언어적으로 표현하면 DNO -> (DNAME, LOC) 또는 DNO는 *(*는 일반 컬럼)를 식별할 수 있다.
* 등가 조인과 비등가 조인
SELECT 테이블1.컬럼, 테이블2.컬럼, ... FROM 테이블1, 테이블2, ...WHERE 조인_조건 AND 일반_조건
- SELECT절에 테이블명을 적어줘야 하지만 참조하려는 테이블중 컬럼명이 유일할 경우 테이블 명 생략 가능
- FROM절에 테이블 2개 이상이 오면 JOIN절
- JOIN 조건의 갯수는 테이블이 n개라고 가정하면 최소 n-1개 이상이다.
- 등호를 사용 하는 등가 조인과 부등호를 사용하는 비등가 조인이 있다.
- 테이블간 관계를 파악하고 있어야 JOIN을 사용할 수 있다.
ex 1) 비등가 조인
안영희의 급여를 보고 sal grade가 몇 인지 조사하는 과정
emp.sal between salgrade.losal and salgrade.hisal -> 이러한 경우 비등가 조인
ex 2) 등가조인
student.sno = score.sno
score.cno = course.cno
course.pno = professor.pno
위의 3가지 구문은 등가 조인이다.
조인문을 만드는 과정
[예제]
#SQL > SELECT eno 사번, ename 이름, emp.dno 부서번호, dept.dno 부서번호, dname 부서명 FROM dept, emp WHERE dept.dno = emp.dno;
-> 각 사원의 근무 부서를 검색
#SQL > SELECT loc 근무처, d.dno 부서번호, dname 부서명, eno 사번, ename 이름 FROM dept d, emp e WHERE d.dno=e.dno AND loc = '광주';
-> 광주에서 근무하는 직원의 명단을 검색(부서번호와 부서명도 검색)
#SQL > SELECT eno 사번, ename 이름, sal*1.1 인상된_급여, grade 등급 FROM emp, salgrade WHERE sal*1.1 BETWEEN losal AND hisal;
-> 각 직원의 급여를 10% 인상 후에 급여 등급을 검색
[실습]
1. 송강 교수가 강의하는 과목을 검색
SELECT p.pname 교수_이름, c.cname 강의하는_과목
FROM professor p, course c
WHERE p.pno = c.pno AND p.pname = '송강';
2. 과목명에 화학이 포함된 과목을 강의하는 교수의 명단 검색
SELECT p.pname 교수_이름, c.cname 화학이_포함된_과목명
FROM professor p, course c
WHERE p.pno = c.pno AND c.cname LIKE '%화학%';
3. 학점이 2학점인 과목과 이를 강의하는 교수를 검색
SELECT p.pname 교수_이름, c.st_num 학점이_2인_과목
FROM professor p, course c
WHERE p.pno = c.pno AND c.st_num = 2;
4. 화학과 교수가 강의하는 과목을 검색
SELECT p.pname 교수_이름, p.section 속한_과, c.cname 강의하는_과목
FROM professor p, course c
WHERE p.pno = c.pno AND p.section = '화학';
5. 화학과 1학년 학생의 기말고사 성적을 검색
SELECT student.sno 학번, student.sname 학생_이름, student.syear 학년, student.major 전공, score.cno 과목_번호, score.result 기말_성적
FROM student, score
WHERE (student.sno = score.sno AND student.syear = 1 AND student.major = '화학') ORDER BY student.sname;
6. 일반화학 과목의 기말고사 점수를 검색
SELECT s.sno 학번, c.cname 과목명, s.result 기말고사_점수
FROM course c, score s
WHERE c.cno = s.cno AND c.cname = '일반화학';
7. 화학과 1학년 학생의 일반화학 기말고사 점수를 검색
SELECT student.major 전공, student.sno 학번, student.sname 학생_이름, student.syear 학년, course.cname 과목명, score.result 기말_성적
FROM student, score, course
WHERE student.sno = score.sno AND course.cno=score.cno AND student.syear = 1 AND student.major = '화학' AND course.cname = '일반화학';
8. 화학과 1학년 학생이 수강하는 과목을 검색
SELECT student.major 전공, student.sno 학번, student.sname 학생_이름, student.syear 학년, course.cname 수강하는_과목, course.st_num 학점
FROM student, score, course
WHERE student.sno = score.sno AND course.cno = score.cno AND student.syear = 1 AND student.major = '화학' ORDER BY course.cname, course.st_num desc;
9. 일반화학 과목에서 평가 점수가 A인 학생의 명단을 검색
SELECT student.sno 학번, student.sname 이름, course.cname 과목명, scgrade.grade 평가_점수
FROM student , scgrade , course , score
WHERE course.cno=score.cno AND student.sno = score.sno AND course.cname = '일반화학' AND score.result BETWEEN loscore AND hiscore AND grade ='A' ;
10. 송강 교수의 과목을 수강하는 학생의 기말고사 점수를 성적 순서로 검색
SELECT student.sno 학번, student.sname 이름, professor.pname 교수, score.result 점수
FROM student, course, professor, score
WHERE student.sno = score.sno AND score.cno = course.cno AND course.pno = professor.pno AND professor.pname = '송강' ORDER BY score.result desc;
11. 화학과 1학년 학생의 기말고사 성적을 학점(A, B, C, D , F)으로 검색
SELECT student.major 학과, student.sno 학번, student.sname 이름, course.cname 과목명, scgrade.grade 학점
FROM student, course, score, scgrade
WHERE student.sno=score.sno AND score.cno=course.cno AND student.syear = 1 AND student.major = '화학' AND score.result BETWEEN loscore AND hiscore ORDER BY scgrade.grade;
12. 송강 교수가 강의하는 과목에서 평가 점수가 A인 학생의 명단을 과목명과 함께 검색
SELECT student.sno 학번, student.sname 이름, professor.pname 교수, course.cname 과목_이름, scgrade.grade 학점
FROM student, course, professor, score, scgrade
WHERE student.sno = score.sno AND score.cno = course.cno AND course.pno = professor.pno AND professor.pname = '송강' AND score.result BETWEEN loscore AND hiscore AND grade ='A';
13. 화학과 1학년 학생에게 강의하는 교수의 명단을 검색
SELECT professor.pname 교수, professor.section 학과, course.cname 과목명
FROM professor, course, student, score
WHERE student.sno = score.sno AND score.cno = course.cno AND course.pno = professor.pno AND student.major = '화학' AND student.syear = 1 ORDER BY professor.pname;
* 자기 참조 조인(self join)
- 참조해야 하는 데이터가 같은 테이블에 있을 경우 테이블을 별도의 명칭으로 출력해서 일반 조인과 같이 사용.
[예제 2]각 사원을 관리하는 사수의 이름을 검색
SELECT e1.eno, e1.ename, e1.mgr, e2.eno, e2.ename
FROM emp e1, emp e2
WHERE e1.mgr = e2.eno;
* 외부 조인(outer join)
- 아직 비어있는 데이터까지 출력해주는 옵션. 대부분 Primary Key가 아닌 Foreign Key에 해당
[예제]
SELECT d.dno 부서번호, dname 부서명, ename 사원명
FROM dept d, emp e
WHERE d.dno = e.dno
ORDER BY 1;
-> 각 부서 별로 사원을 검색. 만약 d.dno는 존재하지만 e.dno는 존재하지 않을 경우 출력이 안 되는 단점이 있다.
SELECT d.dno 부서번호, dname 부서명, ename 사원명
FROM dept d, emp e
WHERE d.dno = e.dno(+)
ORDER BY 1;
-> 사원이 아직 존재하지 않는 부서까지 포함해서 각 부서 별로 사원을 검색.
[실습]
1. 학생 중에 동명이인을 검색
SELECT s1.sno 학번, s2.sname 이름
FROM student s1, student s2
WHERE s1.sname=s2.sname AND s1.sno != s2.sno;
2. 전체 교수 명단과 교수가 담당하는 과목의 이름을 학과 순으로 검색
SELECT p.section 학과, p.pno 교수_번호, p.pname 이름, c.cname 담당_과목
FROM professor p, course c
WHERE p.pno = c.pno(+)
ORDER BY p.section;
3. 이번 학기에 등록 된 모든 과목과 담당 교수를 학점 순으로 검색
SELECT c.cname 과목명, c.pno 담당교수, c.st_num 학점
FROM course c, professor p
WHERE c.pno = p.pno(+)
ORDER BY c.st_num desc;
4. 직원 중에 자신의 관리자보다 급여가 높은 사람의 급여 정보를 관리자 급여 정보와 같이 검색
SELECT e1.eno 사번, e1.ename 이름, e1.sal 급여, e1.mgr 관리자_번호, e2.ename 관리자_이름, e2.sal 관리자_급여
FROM emp e1, emp e2
WHERE e1.mgr = e2. eno AND e1.sal > e2.sal;
5. 교수의 정보와 교수가 담당하는 과목명을 검색
SELECT p.pno, p.pname, p.section, p.orders, p.hiredate, c.cname
FROM professor p, course c
WHERE p.pno = c.pno(+)
ORDER BY p.pno;
6. 직원과 사수의 명단을 검색. 단, 직원 명단은 모든 직원 명단이 출력되어야 함.
SELECT e1. eno 사번, e1.ename 이름, e1.mgr 사수_번호, e2.ename 이름
FROM emp e1, emp e2
WHERE e1.mgr = e2.eno(+);
'Security > sql' 카테고리의 다른 글
SQL-집합연산자, 문자, 숫자, 날짜함수 (0) | 2019.12.09 |
---|---|
SQL-서브쿼리 (0) | 2019.12.06 |
SQL-관계 연산자와 LIKE 연산자, BETWEEN, IN (0) | 2019.12.04 |
SQL-WHERE (0) | 2019.12.03 |
SQL-SELECT(2) (0) | 2019.12.03 |