SQL数据定义
-
基本类型
char(n) | 固定长度的字符串,用户指定长度n |
varchar(n) | 可变长度的字符串,用户指定最大长度n |
int | 整数类型(和机器相关的整数的有限子集) |
smallint | 小整数类型(和机器相关的整数类型的子集) |
numeric(p,d) | 定点数,精度由用户指定。这个数有p位数字(加上一个符号位),其中d位数字在小数点的右边。 |
real,doubleprecision | 浮点数与双精度浮点数,精度与机器相关。 |
float(n) | 精度至少为n位的浮点数 |
-
基本模式定义
--创建一个instructor关系
create table instructor
(ID varchar(5),
name varchar(20) not null
debt_name varchar(20),
salary numeric(8,2),
primary key(ID),
foreign key(dept_name)references department);
--create table命令的通用形式:
create table r
(A1 D1,
A2 D2,
……,
An,Dn,
<完整性约束>
……,
<完整性约束>);
SQL查询的基本操作
--一个典型的SQL查询具有如下形式
select A1,A2,……,An
from r1,r2,……rn
where P;
select distinct dept_name--强行删除重复
select all dept_name--指明不去除重复
--返回一个与instructor一样的关系,只是属性salary的值是原来的1.1倍
select ID,name,dept_name,salary*1.1
from instructor
-
多关系查询
笛卡尔积(Cartesian product):从两个输入关系中输出所有的元组对(无论它们在共同属性上的取值是否相同)。
自然连接(natural join):作用于两个关系,并产生一个关系作为结果。且自然连接只考虑那些在两个关系中都出现的属性上取值相同的元组对。
select A1,A2,……,An
from r1 natural join r2 join r3
where P;
--r1与r2先做自然连接,然后与r3做笛卡尔积。
select A1,A2,……,An
from r1 join r2 using(A1,A2)
where P;
--r1与r2做r1.A1=r2.A1并且r1.A2=r2.A2的合并
基本运算
-
更名运算:
--使用as语句进行更名运算
--可放入selct子句和from子句。
old-name as new-name
--需要比较同一个关系中的元组的情况,如:
--查询:“找出所有工资至少比Biology系某一个教师的工资要高的教师的姓名。”
select distinct T.name
from instructor as T,instructor as S
where T.salary > S.salary and S.dept_name = 'Biology';
在上述查询中,T和S这样被用来重命名关系的标识符在SQL标准中被称作相关名称(correlation name),但通常也被称作表别名(table alias),或者相关变量(correlation variable),或者远元组变量(tuple variable)。
-
字符串运算
SQL中使用各一对单引号来标识字符串。如果单引号是字符串的组成部分,那就用两个单引号字符来表示。
在字符串上可以使用like操作符来实现模式匹配。我们使用一些特殊字符来描述模式:
- 百分号(%):匹配任意子串。
- 下划线(_):匹配任意一个字符。
- 反斜线(\):作为转义字符。
--查询:“找出所在建筑名称中包含子串'Watson'的所有系名”
select dept_name
from department
where building like '%Watson%';
-
selct字句中属性说明
形如select *表示from子句结果关系的所有属性都被选中。
select instructor.*
from instructor,teaches
where instructor.ID = teaches.ID;
-
排列元组的显示次序
order by可以让查询结果中元组按默认的升序顺序显示。
desc表示降序,asc表示升序。
--按salary的降序排列。如果salary相同,按名字的升序排列。
select *
from instructor
order by salary desc,name asc;
-
where子句谓词
所有的谓词前面都可以加上not表示范围取反。
--between比较运算符:
select name
from instructor
where salary between 90000 and 100000;
--用记号(v1,v2,……vn)表示一个n维元组
select name,course_id
from instructor teaches
where (instructor.ID,dept_name)=(teaches.ID,'Biology');
集合运算
并运算union,交运算intersect,差运算except,相当于数学集合论中的 , , - 。
这三个运算都会自动去除重复元素,如果要保留可在后面加上all,比如用union all代替union
- 并运算结果的重复元组数是c1和c2中出现的重复元次数之和。
- 交运算结果中的重复元组数等于在c1和c2中出现的重复元次数里最少的那个。
- 差运算结果中的重复元组数等于在c1中出现的重复元组数减去在c2中出现的重复元组数(前提是此差为正)。
(select course_id
from section
where semester = 'Fall' and year = 2009)
union
(select course_id
from section
where semester = 'Spring' and year = 2010)
空值
- 如果算术表达式的任一输入为空,则该算术表达式结果为空。
- 如果比较运算符涉及到空值,那么结果为unknown。
and的真值表 | |
---|---|
true and unknown | unknown |
false and unknown | unknown |
unknown and unknown | unknown |
or的真值表 | |
---|---|
true or unknown | true |
false or unknown | unknown |
unknown or unknown | unknown |
not的真值表 | |
---|---|
not unknown | unknown |
select name
from instructor
where salary is null--找出所有值为空的
where salary is not null--找出所有值为非空的
如果元组在所有属性上的取值相等,那么它们就被当作相同元组,即使某些值为空。
聚焦函数
- 平均值:avg
- 最小值:min
- 最大值:max
- 总和:sum
- 计数:count
sum和avg的输入必须是数字集,但其他运算符还可作用在非数字数据类型的集合上,如字符串。
--计算平均值需要保留重复元素,否则结果可能会出错。
select avg (salary) as avg_salary
from instructor
--如果需要删除在聚焦函数前重复元素,利用distinct。
select count(distinct ID)
from teaches
--利用count计算一个关系的元组的个数
select count(*)
from course
分组聚焦group by:
- group by子句中的所有属性上取值相同的元组将被分在一个元组中,并在结果中出现。
- group by子句中的属性要么出现在其他聚集函数中,要么在select子句中。否则查询是错误的。
having:
- having子句是针对group by分组后的元组限定条件。
- having子句中的属性要么出现在其他聚集函数中,要么在group by子句中。否则查询是错误的。
select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name
having avg (salary) > 42000;
如果输入是空值,count运算值为0,其他聚集函数返回一个空值。
如果输入包含空值,除count以外的聚集函数会自动忽略空值。
嵌套子查询
select id
from A
where id in(select id from B);
select id
from A
where id exists(select id from B);、
select id
from A
where score > all(select score from B);、
select id
from A
where not unique(select name from B)
--查询所有系中工资总额最大的系
select max(tot_salary)
from(select dept_name,sum(salary))
from instructor
group by dept_name) as dept_total(dept_name,tot_salary);
--标量子查询返回单个值,能够出现在select、where和having子句中
--查询所有的系和它们拥有的教师数
select dept_name,
(select count(*)
from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from departments;
数据库的修改
insert into instructor values(10211,'Smith','Biology',6000);--插入元组
insert into A select id from B; --在查询的基础上插入元组
delete from r where P--删除元组
drop table r;--删除关系
alter table r add A D;--增加属性
alter table r drop A--去掉属性
update r
set salary = salary*1.05--更新元组
where P
update r
set salary = case --利用case结构提供多种更新
when pred1 then result1
when pred2 then result2
……
when predn then resultn
else result.
end;
[参考资料]:《数据库系统概念》 机械工业出版社