数据查询
一、单表查询
1.查询仅涉及一个表,选择表中的若干列
[例1] 查询全体学生的学号与姓名。 SELECT Sno,Sname FROM Student; [例2] 查询全体学生的姓名、学号、所在系。 SELECT Sname,Sno,Sdept FROM Student;
查询全部列
- 选出所有属性列:
- 在SELECT关键字后面列出所有列名
- 将<目标列表达式>指定为 *
[例3] 查询全体学生的详细记录 SELECT Sno,Sname,Ssex,Sage,Sdept FROM Student; 或 SELECT * FROM Student;
查询经过计算的值
- SELECT子句的<目标列表达式>不仅可以为表中的属性列,也可以是表达式
[例4] 查全体学生的姓名及其出生年份。 SELECT Sname,2014-Sage /*假设当时为2014年*/ FROM Student; 输出结果: Sname 2014-Sage 李勇 1994 刘晨 1995 王敏 1996 张立 1995
使用列别名改变查询结果的列标题:
SELECT Sname NAME,'Year of Birth:' BIRTH, 2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT FROM Student; 输出结果: NAME BIRTH BIRTHDAY DEPARTMENT 李勇 Year of Birth: 1994 cs 刘晨 Year of Birth: 1995 cs 王敏 Year of Birth: 1996 ma 张立 Year of Birth: 1995 is
2.选择表中的若干元组
消除取值重复的行
如果没有指定DISTINCT关键词,则缺省为ALL
[例5] 查询选修了课程的学生学号。 SELECT Sno FROM SC; 等价于: SELECT ALL Sno FROM SC; 执行上面的SELECT语句后,结果为: Sno 201215121 201215121 201215121 201215122 201215122
指定DISTINCT关键词,去掉表中重复的行
SELECT DISTINCT Sno FROM SC; 执行结果: Sno 201215121 201215122
常用的查询条件:
1. 比较大小:
[例6] 查询计算机科学系全体学生的名单。 SELECT Sname FROM Student WHERE Sdept=‘CS’; [例7]查询所有年龄在20岁以下的学生姓名及其年龄。 SELECT Sname,Sage FROM Student WHERE Sage < 20; [例8]查询考试成绩有不及格的学生的学号。 SELECT DISTINCT Sn FROM SC WHERE Grade<60;
2. 确定范围:
谓词: BETWEEN … AND …
NOT BETWEEN … AND …
[例9] 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄 SELECT Sname, Sdept, Sage FROM Student WHERE Sage BETWEEN 20 AND 23; [例10] 查询年龄不在20~23岁之间的学生姓名、系别和年龄 SELECT Sname, Sdept, Sage FROM Student WHERE Sage NOT BETWEEN 20 AND 23;
3. 确定集合:
谓词:IN <值表>, NOT IN <值表>
[例11]查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名和性别。 SELECT Sname, Ssex FROM Student WHERE Sdept IN ('CS','MA’,'IS' ); [例12]查询既不是计算机科学系、数学系,也不是信息系的学生的姓名和性别。 SELECT Sname, Ssex FROM Student WHERE Sdept NOT IN ('IS','MA’,'CS' );
- 字符匹配:
- 谓词: [NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <换码字符>’]
- <匹配串>可以是一个完整的字符串,也可以含有通配符%和 _
- % (百分号) 代表任意长度(长度可以为0)的字符串
- 例如a%b表示以a开头,以b结尾的任意长度的字符串
_ (下横线) 代表任意单个字符。 - 例如a_b表示以a开头,以b结尾的长度为3的任意字符串
匹配串为固定字符串 [例13] 查询学号为201215121的学生的详细情况。 SELECT * FROM Student WHERE Sno LIKE ‘201215121'; 等价于: SELECT * FROM Student WHERE Sno = ' 201215121 '; 匹配串为含通配符的字符串 [例14] 查询所有姓刘学生的姓名、学号和性别。 SELECT Sname, Sno, Ssex FROM Student WHERE Sname LIKE '刘%'; [例15] 查询姓"欧阳"且全名为三个汉字的学生的姓名。 SELECT Sname FROM Student WHERE Sname LIKE '欧阳__';
使用换码字符将通配符转义为普通字符
[例16] 查询DB_Design课程的课程号和学分。 SELECT Cno,Ccredit FROM Course WHERE Cname LIKE 'DB\_Design' ESCAPE '\ ' ; [例17] 查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。 SELECT * FROM Course WHERE Cname LIKE 'DB\_%i_ _' ESCAPE '\ ' ; ESCAPE '\' 表示“ \” 为换码字符
5. 涉及空值的查询:
谓词: IS NULL 或 IS NOT NULL
- “IS” 不能用 “=” 代替
[例18] 某些学生选修课程后没有参加考试,所以有选课记录,但没 有考试成绩。查询缺少成绩的学生的学号和相应的课程号。 SELECT Sno,Cno FROM SC WHERE Grade IS NULL [例19] 查所有有成绩的学生学号和课程号。 SELECT Sno,Cno FROM SC WHERE Grade IS NOT NULL;
6.多重条件查询
- 逻辑运算符:AND和 OR来连接多个查询条件
AND的优先级高于OR - 可以用括号改变优先级
[例20] 查询计算机系年龄在20岁以下的学生姓名。
SELECT Sname FROM Student WHERE Sdept= ‘CS’ AND Sage<20;
3.ORDER BY子句
ORDER BY子句
可以按一个或多个属性列排序
升序:ASC;降序:DESC;缺省值为升序
对于空值,排序时显示的次序由具体系统实现来决定
[例21]查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。 SELECT Sno, Grade FROM SC WHERE Cno= ' 3 ' ORDER BY Grade DESC; [例22]查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。 SELECT * FROM Student ORDER BY Sdept, Sage DESC;
4.聚集函数统计元组个数
COUNT(*)
- 统计一列中值的个数
COUNT([DISTINCT|ALL] <列名>) - 计算一列值的总和(此列必须为数值型)
SUM([DISTINCT|ALL] <列名>) - 计算一列值的平均值(此列必须为数值型)
AVG([DISTINCT|ALL] <列名>) - 求一列中的最大值和最小值
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
[例23] 查询学生总人数。 SELECT COUNT(*) FROM Student; [例24] 查询选修了课程的学生人数。 SELECT COUNT(DISTINCT Sno) FROM SC; [例25] 计算1号课程的学生平均成绩。 SELECT AVG(Grade) FROM SC WHERE Cno= ' 1 '; [例26] 查询选修1号课程的学生最高分数。 SELECT MAX(Grade) FROM SC WHERE Cno='1'; [例27 ] 查询学生201215012选修课程的总学分数。 SELECT SUM(Ccredit) FROM SC,Course WHERE Sno='201215012' AND SC.Cno=Course.Cno;
5.GROUP BY子句
GROUP BY子句分组:
细化聚集函数的作用对象
- 如果未对查询结果分组,聚集函数将作用于整个查询结果
- 对查询结果分组后,聚集函数将分别作用于每个组
- 按指定的一列或多列值分组,值相等的为一组
[例28] 求各个课程号及相应的选课人数。 SELECT Cno,COUNT(Sno) FROM SC GROUP BY Cno; 查询结果可能为: Cno COUNT(Sno) 1 22 2 34 3 44 4 33 5 48
HAVING短语与WHERE子句的区别:
- 作用对象不同
- WHERE子句作用于基表或视图,从中选择满足条件的元组
- HAVING短语作用于组,从中选择满足条件的组。