from -> where -> group by -> having -> select ->order by
任何出现在having语句中但未被聚集的属性必须出现在group by语句中
1 2 3 4
select dept_name, avg (salary) from instructor group by dept_name having avg (salary) > 42000;
嵌套子查询
where
集合成员资格
in:若在则true
1 2 3 4 5 6
select count (distinct ID) from takes where (course_id, sec_id, semester, year) in (select course_id, sec_id, semester, year from teaches where teaches.ID= 10101);
not in:不在则true
1 2 3 4 5 6 7
select distinct course_id from section where semester = 'Fall' and year= 2009 and course_id not in (select course_id from section where semester = 'Spring'and year= 2010);
集合比较
some:至少有一个
1 2 3 4 5 6
select name from instructor where salary > some (select salary from instructor where dept name = 'Biology'); #查询工资比同部门至少一个人高的生物系教授的名字
image-20240510195352004
all:全都
1 2 3 4 5 6
select name from instructor where salary > all (select salary from instructor where dept name = 'Biology'); #查找生物系教授中工资最大(比同系其他教授都高)的教授名字
image-20240510195712732
集合约束
空关系验证 exists
1 2 3 4 5 6 7 8
select course_id from section as S #S被称作为相关名称 where semester = 'Fall' and year = 2009 and exists (select * #内查询叫作相关子查询 from section as T where semester = 'Spring' and year= 2010 and S.course_id = T.course_id);
1 2 3 4 5 6 7 8
# Find all students who have taken all courses offered in the Biology department. select distinct S.ID, S.name from 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));
检查是否存在重复元组 unique
unique:存在重复返回false,不存在则返回true
not unique:反之
1 2 3 4 5
#Find all courses that were offered at most once in 2009 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 = 2009);
from
1 2 3 4 5 6 7 8 9 10 11 12
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
定义临时关系,只能在同一查询的后面使用
1 2 3 4 5 6
with max_budget (value) as #max_budget 是临时关系 (select max(budget) from department) select department.name from department, max_budget where department.budget = max_budget.value;
1 2 3 4 5 6 7 8 9 10 11
# Find all departments where the total salary is greater than the average of the total salary at all departments 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;
select
标量子查询:用在 只返回一个包含单个属性的元组的查询 的地方
如果子查询返回多于一个结果的元组会出现error
1 2
select dept_name, ( select count(*) from instructor where department.dept_name = instructor.dept_name) as num_instructors from department;
删除
delete
delet只能删除元组
一个delete只能作用与一个关系上
1 2 3 4 5 6 7 8 9 10 11
#Delete all instructors delete from instructor
#Delete all instructors from the Finance department delete from instructor where dept_name= 'Finance';
#Delete all tuples in the instructor relation for those instructors associated with a department located in the Watson building. delete from instructor where dept_name in ( select dept name from department where building = 'Watson');
1 2 3 4 5 6 7 8
#a funny example: delete from instructor where salary < (select avg (salary) from instructor); #Problem: as we delete tuples from deposit, the average salary changes,边删除平均值边改变 #Solution used in SQL: #1. First, compute avg (salary) and find all tuples to delete #2. Next, delete all tuples found above (without recomputing avg or retesting the tuples)
#Add a new tuple to student with tot_creds set to null insert into student values ('3003', 'Green', 'Finance', null);
系统在执行任何插入之前先执行完select语句十分重要
Otherwise queries like
insert intotable1 select * fromtable1
would cause problem
更新
update
改变某个元组的某个属性的值
update table1
set attribute1 [ ]
where
1 2 3 4 5 6 7 8
#Increase salaries of instructors whose salary is over $100,000 by 3%, and all others by a 5% update instructor set salary = salary * 1.03 where salary > 100000; update instructor set salary = salary * 1.05 where salary <= 100000; #顺序很重要,不能两次更新不能交换位置
case
case
when predict1 then result1
when predict2 then result2
......
else result
end
1 2 3 4 5 6
#可以用case语句进行书写 update instructor set salary = case when salary <= 100000 then salary * 1.05 else salary * 1.03 end
update 与标量子查询
1 2 3 4 5 6 7 8 9 10 11 12
#Recompute and update tot_creds value for all students 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 ); #Instead of sum(credits), use: case when sum(credits) is not null then sum(credits) else 0 end
A view provides a mechanism to hide certain data from the view of certain users.
Any relation that is not of the conceptual model but is made visible to a user as a “virtual relation” is called a view.
视图的定义
1 2
createview v as< query expression > # where<query expression>isany legal SQL expression. The view name is represented by v.
一旦视图被定义,那么这个视图的名字可以用来代指视图产生的虚拟关系
数据库系统存储的是与视图关系相关联的查询表达式
视图关系概念上包含了查询结果的元组但不进行预先计算和存储
视图一旦被创建,在被显示删除之前一直可用
1 2 3
create view faculty as select ID, name, dept_name from instructor
1 2 3 4 5 6 7 8 9 10
# Find all instructors in the Biology department select name from faculty where dept_name = 'Biology' #Create a view of department salary totals create view departments_total_salary( dept_name,total_salary) as select dept_name, sum (salary) from instructor group by dept_name;
用视图定义视图
1 2 3 4 5 6 7 8 9
create view physics_fall_2009 as select course.course_id, sec_id, building, room_number from course, section where course.course_id = section.course_id and course.dept_name = 'Physics'and section.semester = 'Fall' and section.year = '2009';
create view physics_fall_2009_watson as select course_id, room_number from physics_fall_2009 where building= 'Watson';
若视图v1在定义的时候使用了视图v2,则v1直接依赖于v2
若视图v1在定义的时候使用了视图v2,或者视图v1到视图v2之间存在依赖路径,则v1依赖于v2
A view relation v is said to be recursive if it depends on itself.
判断闭包的方法
repeat Find any view relation *v**i* in e1 Replace the view relation *v**i* by the expression defining *vi* until** no more view relations are present in e1
As long as the view definitions are not recursive, this loop will terminate
视图更新
1 2 3 4 5
#向视图中添加新的元组 insertinto faculty values ('30765', 'Green', 'Music'); #This insertion must be represented by the insertion of the tuple # ('30765', 'Green', 'Music', null) # into the instructor relation
sql视图是可更新(插入 删除 更新),若满足下列条件
The from clause has only one database relation.
The select clause contains only attribute names of the relation, and does not have any expressions, aggregates, or distinct specification.
Any attribute not listed in the select clause can be set to null
The query does not have a groupby or having clause.
物化视图
create a physical table containing all the tuples in the result of the query defining the view
tips:
If relations used in the query are updated, the materialized view result becomes out of date
Need to maintain the view, by updating the view whenever the underlying relations are updated.
视图是一种“虚关系”,实际查询时需要根据定义查询底层关系,当存在大量这样的查询时会有较高的成本。
某些数据库支持物化视图,像存储表一样将创建的视图关系“物化”存储在数据库中。
物化视图的创建、修改与删除语法同视图类似,区别是多了关键字 MATERIALIZED
完整性约束
保护数据的一致性
单个关系上的完整性约束
not null 非空
1 2 3
#Declare name and budget to be notnull name varchar(20) notnull budget numeric(12,2) notnull
primary key 主码
既要非空又要保证唯一性
unique 唯一性
1
unique ( A1, A2, …, Am)
让A1,A2,..,Am,成为了超码
声明了唯一性的属性允许为空
check (P), where P is a predicate
关系中的每个元组都要满足谓词P
1 2 3 4 5 6 7 8 9 10 11 12
#ensure that semester isoneof fall, winter, spring or summer: createtable section ( course_id varchar (8), sec_id varchar (8), semester varchar (6), yearnumeric (4,0), building varchar (15), room_number varchar (7), time slot id varchar (4), primary key (course_id, sec_id, semester, year), check (semester in ('Fall', 'Winter', 'Spring', 'Summer')) );
createtable student ( ID varchar (5), name varchar (20) notnull, dept_name varchar (20), tot_cred numeric (3,0) default0, primary key (ID) ) create index studentID_index on student(ID) --------------------------------------------------------------------------------- select* from student where ID = ‘12345' #can be executed by using the index to find the required record, without looking at all records of student
用户自定义类型
1 2 3 4 5 6 7 8
create type Dollars asnumeric (12,2) final
createtable department ( dept_name varchar (20), building varchar (15), budget Dollars ); create type Pounds asnumeric (12,2) final # Pounds和Dollars不是一种类型
域
image-20240520195647678
大对象类型
image-20240520195728022
授权
1 2
grant<privilege list> on<relation name orview name>to<user list>
sql中的权限:
select:allows read access torelation,orthe ability to query using the view
insert:the ability to insert tuples
update:the ability to update using the SQL update statement
delete:the ability to delete tuples.
allprivileges:used as a short form for all the allowable privileges
移除权限
1 2
revoke<privilege list> on<relation name orview name>from<user list>
如果 包含public那么全部的用户会失去权限,除了授权用户
如果相同的权限被不同的人授予给相同的用户两次,那么在被一次撤权后会保留权限。
所有依赖被撤除权限的权限也会被撤除
角色
1 2 3 4 5 6 7
create role instructor grant instructor to Amit # Privileges can be granted to roles: grantselecton takes to instructor # Roles can be granted to users, as well asto other roles create role teaching_assistant grant teaching_assistant to instructor # Instructor inherits all privileges of teaching_assistant
视图的授权
1 2 3 4 5 6
createview geo_instructor as ( select* from instructor where dept_name = ’Geology’); grantselecton geo_instructor to geo_staff
授权的转移
1 2 3 4 5 6 7 8
#允许被授权用户进行授权 grantselecton department to Amit withgrant option; #级联收权,缺省 revokeselecton department from Amit, Satoshi cascade; #显示限定不级联收权 revokeselecton department from Amit, Satoshi restrict; #仅收回授权选项 revokegrant option forselecton department from Amit, Satoshi restrict;
一个用户具有权限等价于授权图中存在由根到用户节点的路径
高级SQL
函数与过程
函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#Define a function that, given the name of a department, returns the count of the number of instructors in that department. createfunction dept_count (dept_name varchar(20)) returnsinteger begin declare d_count integer;
selectcount (* ) into d_count from instructor where instructor.dept_name = dept_name
return d_count; end -------- select dept_name, budget from department where dept_count (dept_name ) >12
referencingoldrowas :for deletes and updates referencingnewrowas : for inserts and updates
1 2 3 4 5 6 7
createtrigger setnull_trigger before updateof takes referencingnewrowas nrow foreachrow when (nrow.grade = ‘ ‘) beginatomic set nrow.grade =null; end;
1 2 3 4 5 6 7 8 9 10 11 12 13 14
createtrigger credits_earned after updateof takes on (grade) referencingnewrowas nrow referencingoldrowas orow foreachrow when nrow.grade <> ’F’ and nrow.grade isnotnull and (orow.grade = ’F’ or orow.grade isnull) beginatomic update student set tot_cred= tot_cred + (select credits from course where course.course_id= nrow.course_id) where student.id = nrow.id; end;
withrecursive rec_prereq(course_id, prereq_id) as ( select course_id, prereq_id from prereq union select rec_prereq.course_id, prereq.prereq_id, from rec_rereq, prereq where rec_prereq.prereq_id = prereq.course_id ) select ∗ from rec_prereq;