七、 分组与计算查询
利用 GROUP BY 子句进行分组计算查询使用得更加广泛。GROUP BY 短语格式如下: GROUP BY GroupColumn[,GroupColunm…][HAVING FilterCondition] 说明: 1. 可按一列或多列分组,还可以用 HAVING 进一步限定分组的条 件。 2. GROUP BY 子句一般跟在 WHERE 子句之后, 没有 WHERE 子 句时, 跟在 FROM 子句之后; HAVING 子句必须跟在 GROUP BY 之后, 不能单独使用。 在查询中是先用 WHERE 子句限定元组, 然后进行分组,最后再用 HAVING 子句限定分组。 例:求每个学生选课的考试成绩平均分。
SELE 学号,AVG(成绩) FROM 选课 GROUP BY 学号 说明:在此查询中,选按学号属性进行分组,然后再计算每个学号的 平均成绩。 例:在选课表中求每个选课门数为 4 门的学生的总分和平均分。 SELE 学号,SUM(成绩) AS 总分,AVG(成绩) AS 平均分; FROM 选课; GROUP BY 学号 HAVING COUNT(*)=4 SELE 姓名,SUM(成绩) AS 总分,AVG(成绩) AS 平均分; FROM 学生 JOIN 选课 ON 学生.学号=选课.学号; WHERE 性别=”女”; GROUP BY 选课.学号 HAVING COUNT(*)=4 例:求平均成绩在 80 分以上的各课程的课程号与平均成绩。 SELE 课程号,AVG(成绩) FROM 选课; GROUP BY 课程号 HAVING AVG(成绩)>80
八、使用空值进行查询
空值的概念: 空值就是缺值或还没有确定值,不能把它理解为任何意义的数据。比 如表示价格的一个字段值,空值表示没有定价,而数值 0 可能表示免 费。空值与空(或空白)字符串、数值 0 等具有不同的含义。 例:假设在选课中有些学生某门课程还没有考试,则成绩为空。试找 出尚未考试的选课信息。
SELE * FROM 选课 WHERE 成绩 IS NULL 注:不能写成“=NULL” 例:试找出成绩不为空的选课信息。 SELE * FROM 选课 WHERE 成绩 IS NOT NULL
九、别名与自联接查询
在联接操作中, 要使用关系名作前缀, 为简单起见, SQL 允许在 FROM 短语中为关系名定义别名。格式为:<关系名><别名> 例:查询选课信息中的姓名,课程名,成绩。 SELE 姓名,课程名,成绩; FROM 学生 S,课程 C,选课 SC; WHERE S.学号=SC.学号 AND C.课程号=SC.课程号 说明:在上面的例子中,别名并不是必须的,但是在关系的自联接操 作中, 别名则是必不可少的。 SQL 不仅可以对多个关系实行联接操作, 也可将同一关系与其自身进行联接,这种联接就称为自联接。在这种 自联接操作关系上,本质上存在着一种特殊的递归联系,也就是关系 中的一些元组, 根据出自同一值域的两个不同的属性, 可以与另外一 些元组有一种对应关系(一对多的联系) 。注:元组即记录。 例:试查询先修课的课程名 在本例中,先修课号与课程号出自同一值域,会涉及自联接查询。 SELE DISTINCT C2.先修课号 C1.课程名; FROM 课程 C1,课程 C2;
WHERE C1.课程号=C2.先修课号
十、内外层相关嵌套查询
前面讨论的嵌套查询是外层查询依赖于内层查询的结果, 而内层查询 与外层查询无关。但有时也需要内、外层互相关的查询,这时内层查 询的条件需要外层查询提供值, 而外层查询的条件需要内层查询的结 果。 例:查询只有一个学生选修的课程的学号,课程号及成绩。 SELE *; FROM 选课 SC1; WHERE SC1.课程号 NOT IN; (SELE 课程号 FROM 选课 SC2 WH