l 单表查询:
SELECT [ALL\DISTINCT]目标列表达式
FROM<表名或视图名>[表名或视图名]…[SELECT语句] AS<别名>
WHERE条件表达式
GROUP BY <列名1>[HAVING<条件表达式>]
ORDER BY <列名2>[ASC/DESC]
GROUP BY 对查询结果按照指定列进行分组,该属性列值相等的元祖为一个组,通常会在魅族中作用聚集函数。
HAVING只有满足指定条件的组才能输出
l 连接查询:
连接条件表示两个表的连接
1. 等值于非等值连接查询:
“=”
SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno=SC.Sno
可能会存在冗余,可以选择在SELECT语句中将需列出来的值列出来。
(1)嵌套循环(NESTED_LOOP)
1. 首先在表1找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元祖,找到后将表1的第一个元组与该元组拼接起来,形成结果表中第一个元组。
2. 表2 全部查找完后,再从表1中找第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。
3. 重复上述操作,直到表1中的全部元组都处理完毕。
(2)排序合并(SORT-MERGE)
1.常用于等值连接
2.首先按照连接属性对表1 表2排序
3.设置指针,分别指向表1和表2的第一个元组,如果这两个元组满足连接条件,则进行元组拼接(如果有多个连续元组满足连接条件,则需要一一拼接),并将两指针分别后移一个元组,否则,将具有较小值的指针后移一个元组。
4.重复上述操作,直到表1或表2的全部元组处理完毕为止。
(3)索引连接(INDEX-JOIN) 可以看做循环嵌套法的变种
1.对表2按连接字段建立索引
2.对表1中的每个元组,依次根据其连接字段查询表2的索引,从中找到满足条件的元组,找到后将表1的第一个元组与该元组拼接起来,形成结果表中一个元组
l 自身连接
一个表与自己进行连接。
需要给表去别名,以表示区别。同名属性区分,需要别名前缀。
查询每门课的之间先修课的名称
SELECTFIRST.Cname, SECOND.Cname
FROMCourse FIRST, Course SECOND
WHEREFIRST.Cpno = SECOND.Cno
l 外连接 左连接 右连接
SELECTSno, Sname, Ssex, Sage,Sdept,Cno,GRADE
FROMStudent LEFT OUT JOIN SC ON
(Student.Sno= SC.Sno)
l 多表连接 两个以上表连接
FROM 表1,表2,表3
l 嵌套查询: 查询语句的嵌套
查询语句中嵌入另一个完整的查询 一个SELECT FROM WHERE为一个查询块允许多层嵌套
上层查询块为外层查询 或父查询
ORDER BY 不能出现在嵌套块,只出现在主查询。
[1] 不相关子查询
子查询条件不依赖父查询
由里向外,逐层处理每个子查询在上层求解
[2] 相关子查询
查询条件依赖父查询 首先取外层的第一个元组看其与内层查询相关的属性值处理内层,WHERE 返回值为真,元组放入结果表。
然后再取元组表的下一个元组,重复过程,直到外层表全部检查完
IN谓词主查询
1. 查询与刘晨在一个系学习的学生
SELECTSno,Sname,Sdept
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname = ‘刘晨’)
或者用自身连接查询:
SELECTS1.Sno,S1.Sname,S1.Sdept
FROMStudent S1,Student S2
WHERES1.Sdept=S2.Stept AND S2.Sname=’刘晨’
带有比较运算符
2.每个学生超过他选修课程平均成绩的课程号 相关子查询
SELECTSno,Cno
FROMSC x 设置一个x为父查询 y为子查询 y需要依赖于x, x中的每一个元组都要依赖于y内查询的元组。
WHEREGrade>=(SELECT AVG(Grade)
FROMSC y
WHEREy.Sno =x.Sno)
带有ALL 或ANY的子查询
3.非计算机科学系比计算机科学系任意一个学生年龄小的学生的姓名和年龄
SELECTSname, Sage
FROMStudent
WHERESage<ANY(SELECT Sage
FROMStudent
WHERESdept=‘CS’)
ANDSdept<>’CS’ 非计算机的学生不是嵌套子查询中的
方法二:用聚集函数
4.年龄小于非计算机最小年龄的学生
SELECTSname, Sage
FROMStudent
WHERESage<
(SELECT MIN(Sage)
FROM Student
WHERE Sdept=’CS’)
ANDSdept<>’CS’
带有EXISTS谓词
EXISTS谓词查询不返回任何数据,只产生逻辑真值‘true’或者逻辑假值‘false’
若内层查询结果非空,则外层的WHERE子句返回真值
若内层查询结果为空,则外层的WHERE子句返回假值
由EXISTS引出的子查询,其目标列表达式通常都用*,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。
5.查询选修一号课程的学生的姓名
SELECTSname
FROM Student
WHERE EXISTS
(SELECT*
FROM SC
WHERE Sno = Student. Sno AND Cno=’1’)
l 集合查询:
UNION 将多个查询合并,自动去掉重复值
UNION ALL 将多个查询结果合并后,保留重复值
1.查询计算机系年龄小于19的学生
SELECT*
FROMStudent
WHERESdept=’CS’
UNION 交集查询可以用INTERSECT代替UNION
SELECT*
FROMStudent
WHERESage<=19
2.同时选修1号课程和2号课程的学生的学号
SELECTSno
FROMSC
WHERECno=’1’ AND Sno IN
(SELECTSno
FROMSC
WHERECno=’2’)
3.查询计算机系学生,且年龄不大于19的学生的差集
SELECT*
FROMStudent
WHERESdept=’CS’
EXCEPT关系代数的减号,相当于求差值
SELECT*
FROMStudent
WHERESage<=19
等价于:SELECT *
FROM Student
WHERE Sdept=’CS’ ANDSage>19