
릴레이션 스키마, 어트리뷰트 타입, 무결성 제약조건, 릴레이션이 가지는 인덱스 집합, 안전성 및 인증 정보, 물리적 스토리지 구조 정보 등을 릴레이션 정보를 구체적으로 정하는 언어
char(n): 고정된 크기의 캐릭터 문자열varchar(n): 최대 n 길이까지의 캐릭터 문자열int: 정수smallint: int보다 더 작은 범위의 정수numeric(p,d): 고정된 포인트 넘버로 정확한(precise) 디지트의 개수가 p이고 그 중 소수점 이후의 수(decimal point)가 d라는 뜻이다. 예를 들어 numeric(3,1)은 44.5를 허용한다.real, double precision: 실수float(n): 최소 n개의 디지트로 표현되는 실수사실상
varchar,int,numeric등을 가장 자주 사용하는 듯하다.
create table로 호출한다.create table instructor(ID char(5), name varchar(20), dept_name varchar(20), salary numeric(8,2));
create table instructor(ID char(5), name varchar(20), dept_name varchar(20), salary numeric(8,2), primary key (ID), foreign key (dept_name) references department);
insert into instructor values('10211', 'Smith', 'Biology', 66000);
특정 튜플을 values 뒤에 괄호로 묶은 튜플로 넣어주는데, 이때 무결성 제약 조건이 존재한다면 침범하지 않는 새로운 값만 삽입 가능하다.
delete from student;
where 조건문을 통해 특정 조건만을 만족하는 튜플만을 없앨 수 있다.drop table r;
alter table r add A D;
alter talbe r drop A;
D를 가진 새로운 어트리뷰트 A가 테이블 r에 추가될 때 기존에 존재하던 다른 튜플들(즉 어트리뷰트 A가 없는 튜플들)의 A는 널 값으로 채워진 채 갱신된다.select A1, A2, ..., An from r1, r2, ..., rm where P;
select distinct dept_name from instructor;
select all dept_name from isntructor;
select * from instructor;
distinct를 붙이고, 그렇지 않으면 all을 붙인다. all이 디폴트다.* 애스터리스크를 사용한다.select ID, name, salary/12 from instructor;
select ID, name, salary/12 as monthly_salary from instructor;
select * from instructor, teaches;
where 절과 함께 사용되는 게 효율적이다.AND, OR, NOT) 및 기타 연산(크기 비교 등)을 통해 조건을 명시할 수 있다.select name from instructor where dept_name = 'Comp. Sci.' and salary > 70000;
select distinct T.name from instructor as T, instructor as S where T.salary > S.salary and S.dept_name = 'Comp.Sci.';
like 연산을 통해 찾으려는 문자열이 어떤 속성을 띠고 있는지 명시할 수 있다.%: 퍼센트 = 서브스트링. 캐릭터가 아니라 서브스트링이기 때문에 문자 개수는 상관없다._: 언터스코어 = 캐릭터. 서브스트링이 아니라 캐릭터이기 때문에 정확한 개수가 중요하다.select name from instructor where name like '%dar%';
dar이 서브스트링으로 존재하는 단어다.Intro% - 시작 문자열이 Intro여야 하는 모든 단어가 리턴된다. %Comp% - 단어 내에 Comp가 서브스트링으로 들어있기만 하면 된다. ___ - 캐릭터 수가 정확히 3개인 단어가 리턴된다. ___% - 캐릭터 수가 적어도 3개인 단어가 리턴된다.select distinct name from instructor order by name;
select distinct name from instructor order by name desc;
asc가 디폴트between이라는 비교 연산자 사용 가능: 부등호를 두 개 사용해도 된다.select name from instructor where salary between 90000 and 100000;
union, 교집합은 intersect, 차집합은 except 연산을 사용한다.all 키워드를 통해 중복 튜플을 계속해서 가지고 있을 수 있다.null: 특정 어트리뷰트 값이 미정이거나 존재하지 않는 상태null이 들어간 산수 연산의 결과값은 언제나 null이다.null이 들어간 비교 연산의 결과값은 언제나 unknown이다.is null이라는 프리디케이트를 통해 체크할 수 있다. 이때 결과값은 true 또는 false이다. 즉 확인 가능하다는 데 주의.select name from isntructor where salary is null;
where절에서 null과 함께 특정 불리언 연산이 사용되면 논리 연산에 따라 결과값이 달라질 수 있다. (1). false가 and 연산에 사용된다면 언제나 false (2). true가 or 연산에 사용된다면 언제나 trueavg, min, max, sum, count를 사용할 수 있다.select avg(salary) from instructor where dept_name = 'Comp.Sci.';
select count(distinct ID) from teaches where semester = 'Spring' and year = 2018;
select count(*) from course;
Group By를 통해 특정 어트리뷰트 도메인 값에 속한 튜플들을 따로 모을 수 있다.select dept_name, avg(salary) as avg_salary from instructor group by dept_name;
group by에 대한 조건문으로 having을 줄 수 있다. select dept_name, avg(salary) as avg_salary from instructor group by dept_name having avg(salary) > 42000;
having절은 그룹이 만들어진 뒤에 선언되어야 하고,where절은 그룹이 만들어지기 전에 선언되어야 한다는 데 주의하자.
select A1, A2, ..., An from r1, r2, ..., rm where P;
select distinct course_id from section where semester = 'Fall' and year = 2017 and course_id in (select course_id from section where semester = 'Spring' and year = 2018);
select distinct T.name from instructor as T, instructor as S where T.salary > S.salary and S.dept_name = 'Biology';
select name from instructor where salary > some(select salary from instructor where dept_name = 'Biology');
some의 의미가 '적어도 하나'임에 주의해서 비교 연산을 사용하자.select name from instructor wher salary > all (select salary from instructor where dept_name = 'Biology');
all의 의미가 '모든'임에 주의하자.true를, 그렇지 않다면 false를 리턴한다.select course_id
from section as S
where semester = 'Fall'
and year = 2017
and exists (select *
from section as T
where semester = 'Spring'
and year = 2018
and S.course_id = T.course_id);
S는 corrleation name, 안쪽 쿼리는 correlated subquery라고 불린다. 안쪽 쿼리에서 바깥 쿼리에서 선언된 이름 T를 where 절의 조건으로 줄 수 있다는 데 주의하자.select distinct S.ID, S.name
fron student as S
where not exists ((select course_id
from course
where dept_name = 'Biology')
except
(select T.course_id
from takes as T
where S.ID = T.ID));
nested 쿼리문 : 생물학 부서가 제공하는 모든 강의 리턴nested 쿼리문 : 특정 학생이 들은 모든 코스를 리턴unique 키워드를 사용해 특정 서브 쿼리가 중복 튜플을 가지고 있는지 확인할 수 있다.select T.course_id
from course as T
where unique ( select R.course_id
from section as R
where T.course_id = R.course_id
and R.year = 2017);
select dept_name, avg_salary
from ( select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name)
where avg_salary > 42000;
select dept_name, avg_salary
from ( select dept_name, avg(salary)
from instructor
group by dept_name)
as dept_avg(dept_name, avg_salary)
where avg_salary > 42000;
with 절이 일어난 쿼리에서만 유효한 임시 릴레이션을 만들 수 있다.with max_budget (value) as
(select max(budge)
from deparment)
select department.name
from department, max_budget
where department.budget = max_budget.value;
max_budget으로 먼저 계산한다. 그리고 예산이 최댓값과 같은 부서의 이름을 리턴한다.with dept_total (dept_name, value) as
(select dept_name, sum(salary)
from instructor
group by dept_name),
dept_total_avg(value) as
(select avg(value)
from dept_total)
select dept_name
from dept_total, dept_total_avg
where dept_total.value > dept_total_avg.value;
dept_total이라는 부서명 + 값과 dept_total_avg이라는 값을 with 절로 선언한 뒤, 평균값이 넘는 부서의 이름만 리턴하는 쿼리문이다.select dept_name,
( select count(*)
from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from department;
delete from instructor;
delete from instructor
where dept_name = 'Finance';
delete from instructor
where dept_name in (select dept_name
from department
where buidling = 'Watson');
delete from instructor
where salary < (select avg(salary)
from instructor);
평균 등
aggregate연산은 현 시점에 존재하는 데이터에 영향을 받는데,delete연산으로 인해 값이 바뀔 수 있다면 에러. SQL은 먼저 연산을 시작하는 시점의 값을 고정한 뒤, 그 값을 계속해서 사용한다.
insert into course
values ('CS-437', 'Database Systems', 'Comp. Sci.', 4);
insert into course (course_id, title, dept_name, credits)
values ('CS-437', 'Database Systems', 'Comp. Sci.', 4);
insert into instructor
select ID, name dept_name, 18000
from student
where dpet_name = 'Music' and total_cred > 144;
update instructor
set salary = salary * 1.05;
update instructor
set salary = salary * 1.05
where salary < 70000;
update instructor
set salary = salary * 1.05
where salary < (select avg(salary)
from instructor);
case 문을 사용한다.update instructor
set salary = case
when salary <= 100000 then salary * 1.05
else salary * 1.03
end;
case ~ end 중 when, when, when... else로 이루어지는 데 주의하자.update student S
set tot_cred = (select sum(credits)
from takes, course
where takes.course.id = course.course_id
and S.ID = takes.ID
and takes.grade <> 'F'
and takes.grade is not null);
tot_cred라는 학생 어트리뷰트 값을 업데이트하는 쿼리문이다.