Select count(*)
from student;
Select count(distinct pID)
from teaches
where semester='Spring' and year=2010;
group by
절
Example>
Select deptName, count(*)
from professor
group by deptName;
Select deptName, avg(salary)
from professor
group by deptName;
사용 시 주의 사항
group by
절에 나온 속성 + 집계 함수만 select절에//Error : pID 때문
Select deptName, pID, avg(salary)
from professor
group by deptName
group by
절에 나온 속성 → select
절에 표시 필수 Xhaving
절group by
절 결과로 생성된 그룹에 대해 임의 조건 명시 → group by
절 필수where
절 : 조건 각 tuple에 적용 → 조건 만족하는 tuple이 다음 단계로 having
절 : 각 그룹에 조건 적용 → 조건 만족하는 그룹이 다음 단계로 → where
절 조건이 적용 후 생성된 그룹에 having
절 조건 적용Select deptName, avg(salary)
from professor
group by deptName
having avg(salary) > 6900;
//Wrong query
Select dname, count(*)
from department, employee
where dnumber = dno and salary > 40000
group by dname
having count(*) > 5;
→ 4만불 이상 소득을 가진 종업원을 5명 이상 가진 부서의 종업원 수 구하기Select dname, count(*)
from department, employee
where dnumber = dno and salary > 40000 and
dno in (select dno from employee
group by dno
having count(*) > 5)
group by dname;
where
절, from
절에서 사용using
→ 공통 속성 = cID
Inner join
myCourse inner join myPrereq on myCourse.cID = myPrereq.cID
//inner 키워드 생략 가능
→ 자연조인이 아닌 일반 조인 : 모든 속성이 결과 테이블에 표시
Outer join
myCourse left outer join myPrereq on myCourse.cID = myPrereq.cID
Natural Outer join
myCourse natural full outer join myPrereq
자연 조인 : 공통으로 존재하는 속성이 조인 속성
조인 속성은 결과 테이블에 한 번만
myCourse natural left outer join myPrereq
myCourse left outer join myPrereq using(cID)
// 두 표현식은 같은 결과 테이블 생성
using : natural 키워드가 없어도 자연 조인 생성
2023.10.12
Select name
from professor
where salary = (select salary from professor where pID='10')
and pID <> '10'; //pID가 10과 같지 않다
from
절에는 위치 XSelect name, salary
from professor
where pID in (10, 21, 22);
//where pID=10 or pID=21 or pID=22;
Select distinct cID
from teaches
where semester = 'Fall' and year = 2009 and
cID in (select cID from teaches
where semester = 'Spring' and year = 2010);
(select cID from teaches where semester = 'Fall' and year = 2009)
intersect
(select cID from teaches where semester = 'Spring' and year = 2010);
Select distinct cID
from teaches
where semester = 'Fall', and year= 2009 and
cID not in (select cID from teaches
where semester = 'Spring' and year = 2010);
(select cID from teaches where semester='Fall' and year=2009)
except
(select cID from teaches where semester='Spring' and year=2010);
Select count(distinct sID)
from takes
where (cID,semester,year) in (select cID,semester,year
from teaches
where pID = 10);
Select count(distinct sID)
from takes, teaches
where pID='10' and teaches.cID=takes.cID and
teaches.semester=takes.semester and teaches.year=takes.year;
(5 < some {0, 5, 6}) //true
(5 = some {0, 5}) //true, == in
(5 != some {0, 5}) //true (0!=5) != not in
(5 < all {0, 5, 6}) //false
(5 = all {4, 5}) //false, !== in
(5 != all {6, 7}) //true, == not in
Select distinct T.name
from professor as T, professor as S
where T.salary > S.salary and S.deptName='CS';
Select name
from professor
where salary > some (select salary
from professor
where deptName='CS');
Select name
from professor
where salary > all (select salary
from professor
where deptName='CS');
Select S.cID
from teaches as S
where S.semester = 'Fall' and S.year = 2009 and
exists (select *
from teaches as T
where T.semester = 'Fall' and T.year = 2010
and S.cID = T.cID); //외부 테이블 사용
일반적으로 의미없는 SQL 문장
Select distinct sID
from student
where exists (select cID
from course
where deptName = 'CS');
→ 외부 from절에 있는 student tuple에 영향을 받지 않는다.
→ 의미없는 where절
not exists
사용Select S.sID, S.name
from student as S
where not exists((select cID
from course
where deptName = 'CS')
except(select T.cID
from takes as T
where S.sID = T.sID));
각 과목별로 2009년 개설된 과목 횟수 count
→ 1 이하 : 과목은 최대 한 번 개설된 것
Select C.cID
from course as C
where 1 >= (select count(T.cID)
from teaches as T
where C.cID = T.cID and T.year = 2009);
Select C.cID
from course as C
where unique (select T.cID
from teaches as T
where C.cID = T.cID and T.year = 2009);
unique{<1, null>, <1, null>} //true
Select deptName, avgSalary
from (select deptName, avg(salary) as avgSalary
from professor
group by deptName)
where avgSalary > 6900;
Select deptName, avgSalary
from (select deptName, avg(salary)
from professor
group by deptName) as deptAvg(deptName, avgSalary)
where avgSalary > 6900;
group by
결과를 임시 결과에 할당 → having
조건을 where
절에 명시 → having
절 필요 XSelect deptName, avg(salary)
from professor
group by deptName
having avg(salary) > 6900;
Select max(totalSalary)
from (select deptName, sum(salary)
from professor
group by deptName) as deptTot(deptName, totalSalary);
Select sum(salary)
from professor
group by deptName
having sum(salary) >= all (select sum(salary)
from professor
group by deptName):
from
절에서 선행 관계, 서브 질의 참조Select name, salary, avg(salary) //Syntax error
from professor
group by deptName;
Select P1.name, P1.salary, avgSalary
from professor P1, lateral (select avg(P2.salary) as avgSalary
from professor P2
where P1.deptName = P2.deptName);
With maxBudget(value) as
(select max(budget)
from department)
select deptName, budget
from department, maxBudget
where department.budget = maxBudget.value;
Select deptName, budget
from department
where budget = max(budget); //wrong SQL
//where 절에서 집계함수 직접 사용 X -> 서브쿼리 이용
Select deptName, budget
from department
where budget = (select max(budget) from department)
with deptTotal(deptName, value) as
(select deptName, sum(salary)
from professor
group bt deptName),
deptTotalAvg(value) as
(select avg(value)
from deptTotal)
select deptName
from deptTotal, deptTotalAvg
where deptTotal.value > deptTotalAvg.value;
2023.10.09
깊게 공부할 필요 X, 해당 기능을 지원한다는 것 정도로만 알고있기
Select top (3) * from professor order by salary;
Select top (10) percent with ties *
from professor
order by salary;
Select * from professor order by salary desc limit 3 offset 1;
//offset 1 : 첫 번째 tuple skip 하는 효과
//상위 봉급자 중 최고를 제외한 3인 검색
Select *
from (select * from professor order by salary desc)
where ROWNUM <= 3;
order by
절 사용Select ID, rank() over (order by GPA desc) as sRank
from studentGrades
order by sRank;
//correlated된 서브질의 형태 -> 비효율적
Select ID, (1 + (select count(*)
from studentGrades B
where B.GPA > A.GPA)) as sRank
from studentGrades A
order by sRank;
Select ID,
rank() over (order by GPA desc nulls last) as sRrank
from studentGrades;
Select ID, deptName,
rank() over (partition by deptName order by GPA desc)
as deptRank
from studentGrades
order by deptName, deptRank;
Select ID, ntile(3) over (order by GPA desc) as quartile
from studentGrades;
ID GPA ID NTILE /* GPA */
S1 2.8 S5 1 /* 4.2 */
S2 3.5 S3 1 /* 4.0 */
S3 4.0 S2 2 /* 3.5 */
S4 3.5 S4 2 /* 3.5 */
S5 4.2 S1 3 /* 2.8 */
간단히 살펴보기
like
Create table t1 like professor
→ 모든 제약 사항 함께 복제 X (primary key, foreign key, indexed 복제 X)as
Create table t2 as (select * from professor) with data;
Create table t3
as (select * from professor where deptName='CS');
photos, videos 를 위한 것
myImage blob(10MB)
create type
사용자가 원하는 데이터 타입 정의Create type Dollars as numeric (12, 2) final;
Create table myDepartment
(deptName varchar(20),
budget Dollars);
create domain
사용자가 원하는 도메인 정의 → create type
과 달리 무결성 제약을 가질 수 있다.Create domain degreeLevel varchar(10)
constraint degreeLevelTest
check (value in ('Bachelor', 'Master', 'Doctorate'));
Create index myCourseIndex on course(cID);