复习
嵌套查询
谓词 in (属于)带有比较运算符构造嵌套查询
判断相关不相关的子查询 就看子查询能不能独立运行
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN --返回“CS”
(SELECT Sdept
FROM Student
WHERE Sname= ‘ 刘晨 ’); --不相关的子查询
--不同的查询方法属于不同的查询
SELECT Sno,Sname,Sdept
FROM Student S1
WHERE EXISTS
(SELECT *
FROM Student S2 --相关的子查询 : 内层子查询无法单独执行
WHERE S2.Sdept = S1.Sdept AND --非空返回ture真值,才会把结果写出来
S2.Sname = '刘晨 ';)
实现全称量词
用EXISTS/NOT EXISTS实现全称量词(难点)
SQL语言中没有全称量词 (For all)
可以把带有全称量词的谓词转换为等价的带有存在量词的谓词:
(x)P ≡ ( x( P))
不 存在 不满足
---NOT EXISTS --查不到结果返回的才是真
--假设:这个学生有一门课没选
[例3.62] 查询选修了全部课程的学生姓名。
SELECT Sname ---找学生
FROM Student
WHERE NOT EXISTS ---满足什么条件的学生?
(SELECT * ----找课程 ---选取所有列;
FROM Course
WHERE NOT EXISTS --- 满足什么条件的课程?
(SELECT * --找满足的选课记录
FROM SC
WHERE Sno= Student.Sno AND --某个学生选择某个课程 -- Sno= Student.Sno 把两个表连接起来
Cno= Course.Cno) --选了所有课程那么这个条件成立
);
用EXISTS/NOT EXISTS实现逻
辑蕴函(难点)
SQL语言中没有蕴函(Implication)
逻辑运算
可以利用谓词演算将逻辑蕴函谓词
p成立,q就成立=>p不成立或者q成立
[例3.63] 查询至少选修了学生201215122选修的全部课
程的学生号码。
解题思路:
用逻辑蕴函表达:查询学号为x的学生,对所有的课
程y,只要201215122学生选修了课程y,则x也选修
了y。
形式化表示:
用P表示谓词 “学生201215122选修了课程y”
用q表示谓词 “学生x选修了课程y”
[例3.63] 查询至少选修了学生201215122选修的全部课
SELECT DISTINCT Sno --- DISTINCT SC里面可能有很多重复记录,所以要去重
FROM SC SCX
WHERE NOT EXISTS
(SELECT *
FROM SC SCY ---提供的201215122学生选修的全部课程
WHERE SCY.Sno = ' 201215122 ' AND NOT EXISTS
(SELECT *
FROM SC SCZ ---提供其他学生选修的全部课程
WHERE SCZ.Sno=SCX.Sno AND
SCZ.Cno=SCY.Cno));
集合查询
1.并操作
形式
<查询块>
UNION
<查询块>
参加UNION操作的各结果表的列数必须相同;对应项的数据类型也必须相同
UNION:将多个查询结果合并起来时,系统自动去掉重复元组。
UNION ALL:将多个查询结果合并起来时,保留重复元组
[例3.64] 查询计算机科学系的学生及年龄不大于19岁的学生。
SELECT *
FROM Student
WHERE Sdept= 'CS'
UNION
SELECT *
FROM Student
WHERE Sage<=19;
--方法二:
SELECT DISTINCT *
FROM Student
WHERE Sdept= 'CS' OR Sage<=19;
[例3.66] 查询计算机科学系的学生与年龄不大于19岁的学生的交集(INTERSECT) 。
SELECT *
FROM Student
WHERE Sdept='CS'
INTERSECT
SELECT *
FROM Student
WHERE Sage<=19
--请使用连接查询写出等价脚本
SELECT *
FROM Student
WHERE Sdept= 'CS' AND
Sage<=19;
--[例3.68] 查询计算机科学系的学生与年龄不大于19岁的学生的差集。
SELECT *
FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT *
FROM Student
WHERE Sage <=19;
--请使用连接查询写出等价脚本
SELECT *
FROM Student
WHERE Sdept= 'CS' AND
Sage>19;
ORDER BY子句只能用于对最终查询结果排序,不能对中间结果排序
任何情况下,ORDER BY子句只能出现在最后
对集合操作结果排序时,ORDER BY子句中用数字指定排序属性
SELECT *
FROM Student
WHERE Sdept= 'CS'
ORDER BY Sno ---不对的;
UNION
SELECT *
FROM Student
WHERE Sage<=19
ORDER BY Sno;
SELECT *
FROM Student
WHERE Sdept= 'CS'
UNION
SELECT *
FROM Student
WHERE Sage<=19
ORDER BY Sno; ---这才是对的;
查询的小结
SELECT [ALL|DISTINCT]
<目标列表达式> [别名] [ ,<目标列表达式> [别名]] …
FROM <表名或视图名> [别名] [ ,<表名或视图名> [别名]] …
[WHERE <条件表达式>]
[GROUP BY <列名1>[,<列名1’>] ...
[HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC] [,<列名2’> [ASC|DESC] ] … ];--排序
如何给列起别名,如何写计算列?
如何去掉重复行?
多个字段排序的顺序是怎样的?
Where和group by都是选择语句,他们的区别是什么?
where 从指定条件中选
group by 就是分组
.
[HAVING <条件表达式>]]
[ORDER BY <列名2> [ASC|DESC] [,<列名2’> [ASC|DESC] ] … ];–排序
如何给列起别名,如何写计算列?
如何去掉重复行?
多个字段排序的顺序是怎样的?
Where和group by都是选择语句,他们的区别是什么?
where 从指定条件中选
group by 就是分组