最为广泛的数据库查询语言:SQL
最初叫做Sequel,现SQL(Structured Query Language,结构化查询语言)
SQL标准支持多种固有类型:
在char(10)类型的属性A中存入字符串"Abc",会在该字符串后追加七个空格;但varchar(10)不会
比较两个不同长度的char 类型的值时,会在短值后面附加恰当的空格使它们长度一致
比较 char 和 varchar 属性时,再不同的数据库中有不同的情况,有时会在短值后附加额外的空格,但有时即使两者长度相同,返回也可能为false。因此,推荐无论何时都是以 varchar 类型而不是 char 类型
create table
定义SQL关系:
create table department
(dept_name varchar(20),
building varchar(15),
budget numeric(12,2),
primary key(dept_name));
primary key(A,B,…,C):主码,主码属性必须是非空且唯一的。可以使用多个属性作为联合主码
foreign key(A,B,…,C) references s:外码声明表示关系中任意元组在属性上的取值必须对应于关系s中某元组在主码属性上的取值
not null:一个属性的非空约束,在该属性上不允许出现空值
drop tbale r
:删除r中的所有元组,还删除r 的模式
delete from r
:保留关系r,但删除r中的所有元组
alter table r add A D
:为已存在关系r添加属性A,A是属性名,D是属性类型
alter table r drop A
:从已存在关系r去掉属性A。很多数据库不支持
SQL查询的基本结构由三个子句构成:select、from、where
select A1,A2,A3 from r where A1 = "hello" and A2 > 2000
where 子句中允许使用and、or、not,运算对象可以包括<、<=、=等表达式。
SQL允许我们使用比较运算符比较字符串、算术表达式、以及特殊类型,比如日期类型
select A1,a.A2,A3 from a,b where a.A2 == b.A2
select A1,S.A2,A3 from student as S,teacher as T where S.A2 == T.A2
在SQL使用一对单引号来标识字符串,如果单引号是字符串的组成部分,那就用两个单引号字符来标识,如“I’m so sorry”表示为’I’‘m so sorry’
在一些数据库,如MySql 、SQL Server 中,匹配字符串时并不区分大小
SQL 还支持多种函数:
在字符串上可以使用like运算符来实现运算模式匹配:
“ \ ”转为转义字符
select * from student order by name
默认升序 隐藏了最后的 asc
select * from student order by name desc
降序
between…and… select * from student where age between 1 adn 18
a >= b 且 c >= d 等价于(a,b) >= (c,d)
union 进行并运算,并自动去重。如果想要保留所有重复项,使用union all
(select course_id
from section
where year = 2017)
union
(select course_id
from section
where year = 2020)
intersect 进行交运算,并自动去重。如果想要保留所有重复项,使用intersect all
(select course_id
from section
where year = 2017)
intersect
(select course_id
from section
where year = 2020)
找出在2017开设但不在2020开设的课程,如果想要保留重复项,使用except all:
(select course_id
from section
where year = 2017)
except
(select course_id
from section
where year = 2020)
SQL在涉及空值的任何比较运算的结果是为 unknown(既不是谓词 is null,也不是 is not null),这创建了在 true和false 之外的第三种逻辑值。(一些数据库不支持 unknown)
where 对于任何一个计算出 false 和unknown 的元组都不能加入结果
聚合函数是以值集(集合或多重集合)为输入并返回单个值的函数
SQL提供了五个标准的固有聚集函数:
select avg(salary) as avg_salary
from teachers
where teachers.age = 28;
select count(distinct ID)
from teaches
where semester = 'Spring' and year = 2017;
找出每个系的平均工资
select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name;
**注意:**任何没有出现在group by 子句中的属性如果出现在select子句中,它只能作为聚合函数中的参数,否则这样的查询就是错误的。
having 针对 group by 子句构成的每个分组。
select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name
having avg(salary) > 42000
在使用 avg 时,如果输入的数据有空值怎么办?
除了count(*)之外的所有的聚集函数都忽略其输入集合中的空值。如此聚集函数的输入值可能为空值,规定空集的count运算值为0,并且当作用在空值上时,其他所有聚集运算返回一个空值。
以下代码中,括号中的查询就是子查询
select name,age
from teachers
where age > 25 and name in (select name,age
from teachers
where salary > 10000)
找出工资至少比Biology系某位教师的工资要高的所有教师的名字:
select name
from instructor
where salary > some(select salary
from instructor
where dept_name = 'Biology')
找出工资比Biology系每个教师的工资要高的所有教师的名字:
select name
from instructor
where salary > all(select salary
from instructor
where dept_name = 'Biology')
exists结构在作为参数的子查询非空时返回true值
not exists
select course_id
from section 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)
如果在作为参数的子查询结果中没有重复的元组,则 unique 结构返回 true 值
not 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 T.course_id
from course as T
where 1>=(select R.course_id
from section as R
where T.course_id = R.course_id and
R.year = 2017)
SQL允许在from子句中使用子查询表达式。
select dept_name,avg_salary
from(select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name)
where avg_salary>=4200
with子句提供了一种定义临时关系的方式。(大多数数据库支持)
with max_budget(value) as
(select max(budget)
from department)
select budget
from department,max_budget
where department.budget = max_budget.value;
标量子查询:只返回一个包含单个属性的元组
SQL允许标量子查询出现在返回单个值的表达式能够出现的任何地方
select dept_name,
(select count(*)
from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from department;
delect from r where P
P代表一个谓词,在关系r中所有满足P的元组都将被删除
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 dept_name = 'Music' and tot_cred > 144
大部分关系数据库产品都有特殊的“bulk loader”工具,它可以向关系中插入一个非常大的元组集合。这些工具允许从格式化的文本文件中读出数据,并且它们的执行速度比等价的插入语句序列要快得多。
update instructor
set salary = salary * 1.05
where salary > 15000;
SQL提供case结构:
update instructor
set salary = case
when salary <= 100000 then salary * 1.05
else salary * 1.03
end
case 结构:
case
when pred1 then result1
when pred2 then result2
...
when predn then resultn
else result0
end