数据查询是数据库的核心操作
单表查询
选择表中的列:
等同于=关系代数的投影
(1)查询全体学生的学号和姓名
SELECT Sno,Sname //注意列的顺序 FROM Student;(2)查询全体学生的详细记录
SELECT * //也可列出全部的属性 FROM Student;(3)查询全体学生的姓名及其出生年份
SELECT Sname,2014-Sage FROM Student;(4)查询全体学生的姓名、出生年份和所在的院系,要求用小写字母表示系名,通过指定别名来改变查询结果的列标题
SELECT Sname '名字', 'X' BIRTH, 2014-Sage birthday, LOWER(Sdept) department FROM Student;
选择表中的元组(行)
(1)查询选修了课程的学生学号
SELECT DISTINCT Sno //如果去掉结果表中的重复的行,必须指定 DISTINCT ,SELECT Sno 等价于 SELECT ALL Sno FROM SC;(2)比较:查询计算机科学系全体学生的名单
SELECT Sname FROM Student WHERE Sdept='CS';(3)比较:查询所有年龄在20岁以下的学生姓名及其年龄
SELECT Sname,Sage FROM Student WHERE Sage<20;(4)比较:查询考试成绩不及格的学生的学号
SELECT DISTINCT Sno //去掉重复的学号 FROM SC WHERE Grade<60;(5)范围:查询年龄在20~23(包括20岁和23岁)岁之间的学生姓名、系别和年龄
SELECT Sname,Sdept,Sage FROM Student WHERE Sage BETWEEN 20 AND 23; //查询不在20~23的用 NOT BETWEEN(6)集合:查询系 CS、MA 和 IS 学生的姓名和性别
SELECT Sname,Ssex FROM Student WHERE Sdept IN ('CS','MA','IS'); //查询不是这些系的用 NOT IN
(7)字符匹配,使用LIKE关键字: %代表任意长度的字符串 _代表任意单个字符
①查询学号为 201215121 的学生的详细情况
SELECT * FROM Student WHERE Sno LIKE '201215121'; //等价于 Sno='201215121';
②查询所有姓刘的学生的姓名、学号和性别
SELECT Sname,Sno,Ssex FROM Student WHERE Sname LIKE '刘%';
③查询姓“欧阳”且全名为三个汉字学生的姓名
SELECT Sname FROM Student WHERE Sname LIKE '欧阳_';
④查询名字中第二个字为“阳”的学生的姓名和学号
SELECT Sname,Sno FROM Student WHERE Sname LIKE '_阳%';
⑤查询所有不姓刘的学生的姓名,学号和性别
SELECT Sname。Sno,Ssex FROM Student WHERE Sname NOT LIKE '刘%';
⑥查询 DB_Design 课程的课程号和学分
SELECT Cno,Ccredit FROM Course WHERE Cname LIKE 'DB\_Design ' ESCAPE'\'; //使用转码字符 \ 来转义普通的 _ 字符
⑦查询以“DB_” 开头,且倒数第三个字符为 i 的课程的详细情况
SELECT * FROM Course WHERE Cname LIKE 'DB\_%i_ _' ESCAPE'\';
(8)空值:查询缺少成绩的学生的学号和相应的课程号
SELECT Sno,Cno FROM SC WHERE Grade IS NULL; //查询有成绩的用 IS NOT NULL
(9)多重条件: AND 和 OR
①查询计算机科学系年龄在20岁以下的学生姓名
SELECT Sname FROM Student WHERE Sdept='CS' AND Sage<20;
②查询系 CS、MA 和 IS 学生的姓名和性别
SELECT Sname,Ssex FROM Student WHERE Sdept='CS' OR Sdept='MA' OR Sdept='IS'; //IN 谓语实际上是多个 OR 运算符的缩写
ORDER BY子句:
对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序
(1)查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排序
SELECT Sno,Grade FROM SC WHERE Cno='3' ORDER BY Grade DESC;(2)查询全体学生情况,结果按所在系的系号升序排序,同一个系中的学生按年龄降序排序
SELECT * FROM Student ORDER BY Sdept,Sage DESC;
聚集函数:
COUNT:统计 SUM:计算总和 AVG:计算平均值 MAX:一列的最大值 MIN:一列的最小值
(1)查询学生总人数
SELECT COUNT(*) FROM Student;
(2)查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno) //去掉重复计算学生的人数 FROM SC;(3)计算选修 1 号课程的学生平均成绩
SELECT AVG(Grade) FROM SC WHERE Cno='1';(4)查询选修 1 号课程的学生最高分数
SELECT MAX(Grade) FROM SC WHERE Cno='1';(5)查询学生 201215012 选修课程的总学分数
SELECT SUM(Ccredit) FROM SC,Course WHERE Cno='201215012' AND SC.Cno=Course.Cno; //两表连接
GROUP BY子句:
将查询结果按某一列或多列的值分组,值相等的为一组
(1)求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno) FROM SC GROUP BY Cno;(2)查询选修三门以上课程的学生学号
SELECT Sno FROM SC GROUUP BY Sno HAVING COUNT(*)>3; //WHERE子句作用于表或视图,从中选择满足条件的元祖。HAVING短语作用于组,从中选择满足条件的组(3)查询平均成绩大于等于 90 分的学生学号和平均成绩
SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno HAVING AVG(Grade)>=90;
连接查询
一个查询涉及两个以上的表,使用连接查询
查询等值与非等值连接查询
(1)查询每个学生及其选修课程的情况
SELECT Student.*,SC.* FROM Student,SC WHERE Student.Sno=SC.Sno; //要求是表 Student 和表 SC 的同一个学生(2)查询每个学生及其选修课程的情况,使用自然连接,可以把列中重复的属性去掉
SELECT Student.Sno,Snam,Ssex,Sage,Sdept,Cno,Grade FROM Student,SC WHERE Student.Sno=SC.Sno;(3)查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
SELECT Student.Sno,Sname FROM Student,SC WHERE Student.Sno=SC.Sno AND SC.Cno='2' AND SC.Grade>90;
自身连接
(1)查询每一门的间接先行课(就是先修课的先修课)
SELECT FIRST.Cno,SECOND.Cpno FROM Course FIRST,Course SECOND WHERE FIRST.Cpno=SECOND.Cno;
外连接
(1)查询每个学生及其选修课程的情况
SELECT Student.Sno,Snam,Ssex,Sage,Sdept,Cno,Grade FROM Student LEFT OUTER JOIN SC ON(Student.Sno=SC.Sno); // 左 外 连接
多表连接
(1)查询每个学生的学号、姓名、选修的课程名及成绩
SELECT Student.Sno,Sname,Cname,Grade FROM Student,SC,Course WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno; //注意连接顺序
嵌套查询
带有 IN 谓语的子查询
(1)查询与“刘晨”在同一个系学习的学生
SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN( SELECT Sdept FROM Student WHERE Sname='刘晨' );可用自身连接来完成
SELECT S1.Sno,S1.Sname,S1.Sdept FROM Student S1,Student S2 WHERE S1.Sdept=S2.Sdept AND S2.Sname='刘晨';(2)查询选修了课程名为“信息系统”的学生号和姓名
...
带有比较的子查询
(1)找出每个学生超过他自己选修课程平均成绩的课程号
SELECT Sno,Cno FROM SC x WHERE Grade >=( SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno );
带有ANY(SOME) 或 ALL 谓词的子查询
(1)查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄
SELECT Sname,Sage FROM Student WHERE Sage<ANY( SELECT Sage FROM Student WHERE Sdept='CS') AND Sdept!='CS'; //!=等同于<>(2)查询非计算机科学系中比计算机科学系所有学生年龄小的学生名字及年龄
SELECT Sname,Sage FROM Student WHERE Sage<ALL( SELECT Sage FROM Student WHERE Sdept='CS') AND Sdept!='CS';
带有 EXISTS 谓语的子查询
...集合查询
SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作。
集合的操作主要包括并(UNION)、交(INTERSECT)、差(EXCEPT)
(1)查询计算机科学系的学生及年龄不大于19岁的学生
SELECT * FROM Student WHERE Sdept='CS' UNION SELECT * FROM Student WHERE Sage<=19;
(2)查询选修了课程1或者选修课程2的学生
SELECT Sno FROM SC WHERE Cno='1' UNION SELECT Sno FROM SC WHERE Cno='2';(3)查询计算机科学系的学生与年龄不大于19岁的学生的交集
SELECT * FROM Student WHERE Sdept='CS' INTERSECT SELECT * FROM Student WHERE Sage<=19; //实际上就是查询系中不大于19岁的学生:WHERE Sdept='CS' AND Sage<=19;(4)查询即选修课程1又选修课程2的学生,就是查询选修课程1的学生集合与选修课程2的学生集合的交集
SELECT Sno FROM SC WHERE Cno='1' INTERSECT SELECT Sno FROM SC WHERE Cno='2'; //等同于:WHERE Cno='1' AND Sno IN(SELECT Sno FROM SC WHERE Cno='2');(5)查询计算机科学系的学生与年龄不大于19岁的学生的差集
SELECT * FROM Student WHERE Sdept='CS' EXCEPT SELECT * FROM Student WHERE Sage<=19; //实际上就是查询系中年龄大于19岁的学生:WHERE Sdept='CS' AND Sage>19;
基于派生表的查询
....