SQL语言之关系运算与多表操作(五)
关系代数
SQL语言:并运算UNION, 交运算INTERSECT, 差运算EXCEPT。
基本语法形式: 子查询{ Union [ALL] |Intersect [ALL]|Except [ALL] 子查询}
通常情况下自动删除重复元组:不带ALL。若要保留重复的元组,则要带 ALL。
假设子查询1的一个元组出现m次,子查询2的一个元组出现n次 ,则该元组在:
子查询1 Union ALL 子查询2,出现m + n次
子查询1 Intersect ALL 子查询2,出现min(m,n)次
子查询1 Except ALL 子查询2,出现max(0, m –n)次
并运算
#求学过002号课的同学或学过003号课的同学学号
Select student_id From SC Where couse_id = ‘002’
UNION
Select student_id From SC Where couse_id = ‘003’;
#上述语句也可采用如下不用UNION的方式来进行
Select student_id From SC Where couse_id = ‘002’ OR C# = ‘003’;
交运算
#求既学过002号课,又学过003号课的同学学号
Select student_id From SC Where course_id = ‘002’
INTERSECT
Select student_id SC Where course_id = ‘003’;
#上述语句也可采用如下不用INTERSECT的方式来进行
Select student_id From SC
Where C# = ‘002’ and
student_id IN (Select student_id From SC Where course_id = ‘003’);
交运算符Intersect并没有增强SQL的表达能力,没有Intersect,SQL也 可以用其他方式表达同样的查询需求。只是有了Intersect更容易表达一些, 但增加了SQL语言的不唯一性
差运算
#假定所有学生都有选课,求没学过002号课程的学生学号
Select DISTINCT student_id From SC
EXCEPT
Select student_id SC Where course_id = ‘002’
#前述语句也可不用EXCEPT的方式来进行
Select DISTINCT student_id From SC SC1
Where not exists
(Select * From SC Where course_id = ‘002’ and course_id = SC1.student_id) ;
差运算符Except也没有增强SQL的表达能力,没有Except,SQL也可以用 其他方式表达同样的查询需求。只是有了Except更容易表达一些,但增加了 SQL语言的不唯一性
空值检测 is[not ] null
#找出年龄值为空的学生姓名
Select name From Student Where age is null;
#注意:上例条件不能写为Where Sage = null;空值是不能进行运算的
小结
除is[not]null之外,空值不满足任何查找条件
如果null参与算术运算,则该算术表达式的值为null
如果null参与比较运算,则结果可视为false。在SQL-92中可看成 unknown
如果null参与聚集运算,则除count(*)之外其它聚集函数都忽略null
内连接、外连接
Select 列名[ [, 列名] …]
From 表名1[NATURAL] [ INNER | { LEFT | RIGHT | FULL} [OUTER]]
JOIN 表名2 { ON 连接条件| Using (Colname{, Colname…})}
[ Where 检索条件] …;
连接类型(四者选一) inner join, left outer join, right outer join, full outer join
连接条件(三者选一)natural, on <连接条件> ,using (Col1, Col2, ..., Coln)
连接中使用natural
出现在结果关系中的两个连接关系的元组在公共属性上取值相等,且 公共属性只出现一次
连接中使用on <连接条件>
出现在结果关系中的两个连接关系的元组取值满足连接条件,且公共 属性出现两次
连接中使用using (Col1, Col2, ..., Coln)
(Col1, Col2, ..., Coln)是两个连接关系的公共属性的子集,元组在(Col1, Col2, ..., Coln)上取值相等,且(Col1, Col2, ..., Coln)只出现一次
Inner Join
#求所有教师的任课情况并按教师号排序(没有任课的教师也需列在表中)
Select Teacher.id, Teacher.name, Course.name From Teacher
Inner Join Course ON
Teacher.id = Course.teacher_id Order by Teacher.id ASC;
OuterJoin
#求所有教师的任课情况(没有任课的教师也需列在表中)
Select Teacher.id, Teacher.name, Course_name From Teacher
Left Outer Join Course ON
Teacher.id = Course.teacher_id Order by Teacher.id ASC;