单表查询示例Student表:
Student表
| 学号(Sno) | 姓名(Sname) | 性别(Ssex) | 年龄(Sage) | 所在系(Sdept) |
|---|---|---|---|---|
| 201215121 | 李勇 | 男 | 20 | CS |
| 201215122 | 刘晨 | 男 | 19 | CS |
| 201215123 | 王敏 | 女 | 18 | MA |
| 201215125 | 张丽 | 女 | 19 | IS |
Course表
| 课程号(Cno) | 课程名(Cname) | 先行课(Cpno) | 学分(Ccredit) |
|---|---|---|---|
| 1 | 数据库 | 5 | 4 |
| 2 | 数学 | 2 | |
| 3 | 信息系统 | 1 | 4 |
| 4 | 操作系统 | 6 | 3 |
| 5 | 数据结构 | 7 | 4 |
| 6 | 数据处理 | 2 | |
| 7 | PASCAL语言 | 6 | 4 |
SC表
| 学号(Sno) | 课程号(Cno) | 成绩(Grade) |
|---|---|---|
| 201215121 | 1 | 92 |
| 201215121 | 2 | 85 |
| 201215121 | 3 | 88 |
| 201215122 | 2 | 90 |
| 201215122 | 3 | 780 |
查询若干列
- 查询指定列
select Sno,Sname from Student;
查询Student表中所有的学号和姓名作为新的关系结果输出.
- 查询表所有的内容
select Sno,Sname,Ssex,Sage,Sdept from Student;
你觉得太累可以这样写,两个语句的效果是一样的.
select * from Student;
- 查询一些计算过的值
select Sname,2014-Sage as birth from Student;//2014-Sage,一个算术表达式
其查询结果为:
| 姓名(Sname) | 2014-Sage |
|---|---|
| 李勇 | 1994 |
| 刘晨 | 1995 |
| 王敏 | 1996 |
| 张丽 | 1995 |
- 查询所有学生的姓名,出生年月,所在院系(要求用小写字母表示)
select Sname,'出生年月',2014-Sage,lower(Sdept) from Student;
结果为:
| Sname | '出生年月'| 2014-Sage| lower(Sdept)|
|-------------- |--------------:|--------------:|--------------:|:--------------:|
| 李勇 | 出生年月 | 1994 | cs |
| 刘晨 | 出生年月 | 1995 | cs |
| 王敏 | 出生年月 | 1996 | ma |
| 张丽 | 出生年月 | 1995 | is |
- 定义列表的别名
select Sname NAME,'Year of Birth:' BIRTH,2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT from Student;
等价于as的用法,用作其他别名;
select Sname as NAME,'Year of Birth:' as BIRTH,2014-Sage as BIRTHDAY,lower(Sdept) DEPARTMENT from Student;
查询若干元组(表中的一行即为一个元组)
- 查询选修了课程的学生号
select Sno from SC;//等价于 select all Sno from SC;
- distinct 去掉重复的元素
select distinct Sno from SC;
- 查询满足条件的元组
除了最常用的关键字where之外,还有一些常用的查询条件;
常用的查询条件
| 查询条件 | 谓词 |
|---|---|
| 比较 | =(d等于), >(大于), <, >=, <=, !=, <>(不等于), !>(不大于), !<(不小于), |
| 确定范围 | between and ,not between and |
| 确定集合 | in ,not in |
| 字符匹配 | like, not like |
| 空值 | is null,is not null |
| 多重条件(逻辑运算) | and ,or,not |
比较大小
- where 关键字
select Sname from Student where Sdept='CS';
结果如图:
- 满足年龄小于20的
select Sname,Sage from Student where Sage<20;
- 查询考试不及格的学生学号
select distinct Sno from SC where Grade<60;
确定范围(between...[between后是范围的下限]and...[and是范围的上限])
- 查询20-23岁(包含20 23岁)的学生信息
select * from Student where Sage between 20 and 23;
- 不包含20-23岁的学生信息
select * from Student where Sage not between 20 and 23;
确定集合(就是查找属于指定集合的元组)
- 查找CS,MA,IS系的学生信息
select * from Student where Sdept in ('CS','MA','IS');
- 查找不属于1中科系的学生信息
select * from Student where Sdept not in ('CS','MA','IS');
字符匹配(关键字 like, % [代表任意长度,可以为0,的字符串], _ [代表任意单个字符串])
%(百分号)代表任意长度(长度可以为0)的字符串,例如a%b表示以a开头,以b结尾的任意长度的字符串,如 acb, addgb, ab等都满足该匹配串.
_(下划线)代表任意单个字符:例如a_b表示以a开头,b结尾的长度为3的字符串.
- 查询学号为xxx的学生详细情况
select * from Student where Sno like '201215121';//like,模糊查询
select * from Student where Sno ='201215121';
若like后面的匹配串不含通配符,则可以用=取代, not like 用<>或not like代替.
- 查询所有姓刘的学生信息
select * from Student where Sname like '刘%';
- 查询姓名为'欧阳'且三个汉字的学生姓名
select Sname from Student where Sname='欧阳_';//注:当字符集是ASCII时需要两个_,当字符集为GBK时只需要一个
- 名字第二个字为'阳'的学生信息
select * from Student where Sname='_阳%';
- 查询不姓刘的学生信息
select * from Student where Sname not like '刘%';
- 查询"DB_Design"课程号和学分
select Cno,Ccredit from CS where Cname like 'DB\_Design' escape '\';
escape ''表示''为转码字符,这样匹配串中的'_'就不在具有通配符的含义.
- 查询以"DB_"开头,切倒数第三个字符为i的课程的信息
select * from Course Where Cname like 'DB\_%i__' escape '\';
后面两条下划线前面没有'',所以后两条下划线仍然具有通配符的功能.
涉及空值的查询
- 查询成绩为空的学生的课程号和学号
select * from SC where Grade is null; //此处is不能用=替换
- 查询成绩不为空的学生课程号和学号
select * from SC where Grade is not null;
多重条件查询
- 查询计算机系年龄在20岁以下的学生信息
select * from Student where Sdept='CS' and Sage<20;
order by 子句
order by 子句对查询结果按照一个或者多个属性列的升序(ASC)或者降序(DESC),默认升序;
- 查询选修了三号课程学生的学号及成绩,按分数的降序输出
select * from SC where Cno='3' order by Grade desc;
- 查询所有学生信息,结果按所在系的系号升序,同一系的学生按年龄降序输出
select * from Student order by Sdept,Sage Desc;
聚集函数
| 函数 | 作用 |
|---|---|
| COUNT(*) | 统计元组个数 |
| COUNT([distinct,all]<列名>) | 统计一个列中值的个数 |
| SUM([distinct,all]<列名>) | 计算一列值的总和(此列必须是数值类型) |
| AVG([distinct,all]<列名>) | 计算一列值的平均数(此列必须是数值类型) |
| MAX([distinct,all]<列名>) | 求一个列值中的最大值 |
| MIN([distinct,all]<列名>) | 求一个列值中的最小值 |
如果指定distinct短语,则表示再计算时去掉重复的值,如果不指定distinct或者all短语,则表示不取消重复值
- 查询学生总人数
select count(*) from Student;
- 查询选修了课程的学生人数
select count(distinct Sno) from SC;
- 选修1号课程学生平均成绩
select AVG(Grade) from SC where Cno='1';
- 选修1号课程学生的最高分
select Max(Grade) from SC where Cno='1';
- 查询学生201215012选修课程的总学分数
select Sum(Ccredit) from SC,Course where Sno='201215012' and SC.Cno=Course.Cno;
Group by子句
group by 子句将查询结果按某一列或者多列的值分组,值相等的为一组.
- 求各个课程号及相应的选课人数
select Cno,Count(Sno) from SC Group by Cno;
- 选修了三门以上课程的学生学号
如果分组后还要求按照一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用Having短语;
select Sno From SC group by Sno Having Count(*)>3;
这里先用group by 子句按Sno进行分组,再用聚集函数count对每一组计数,Having短语给出了选择组的条件,只有满足条件(即元组个数>3,表示此学生选修的课程超过3门)的才会被选出来.
where 子句与having短语的区别在于作用对象不同,where子句作用于基本表或视图,Having作用于组.
- 查询平均成绩大于等于90的学生号和平均成绩
错误写法
select Sno,AVG(Grade) from SC where AVG(Grade)>=90 group by Sno;
正确写法
select Sno,AVG(Grade) from SC group by Sno Having AVG(Grade)>=90;









网友评论