数据查询
基础语法
select[all|distinct]<目标列表达式>
from <表名或者视图名>
where<条件表达式>
group by <列名1>[having<条件表达式>]
order by <列名2>[ASC|DESC]
含有having的条件表达式必须跟在group后面 不可以跟在where后面
例如:
查询平均成绩大于等于90的学生学号和平均成绩
正确答案
select sno avg(grade)
from sc
group by sno having avg(grade) >= 90
错误答案
select sno avg(grade)
from sc
where having avg(grage) >= 90
group bu sno
group by语句
group by 语句的目的是为了细化聚焦函数的作用对象,使得每一个元组都有一个函数值,否则聚焦函数的对象就是整个表,如果group by后面跟有having语句,则只有符合having语句条件的才会显示出来
聚焦函数
count(*) -统计元组个数
count([distinct|all]<列名>) -统计一列中值的个数
sum([distinct|all]<列名>) -求和
avg([distinct|all]<列名>) -取平均值
max([distinct|all]<列名>) -取最大值
min([distinct|all]<列名>) -取最小值
求选修了三门课程以上的学生学号
select sno
from sc
group by sno having count(*) > 3;
--存疑:是否可以是count(cno)
其他基础语法
where常用的查询条件
比较 = > < >= <=
!= 或<>(代表不等于)
确定集合 in not in
字符匹配 like not like
多重逻辑条件 and or not
例如查询计算机科学系 信息系 数学系 所有学生的名字中第二个是“阳”的学生的学号和姓名
select sno sname
from student
while sname like '_阳%' and
sdept in('cs','is','ma');
连接
连接之中有一个自身连接,在自身连接时候要取两个别名
例如:查询每一门课的间接先修课
首先要分别为course表起别名为fir,sec
selcet fir.cno sec.cpno
from course fir course sec
where fir.cno = sec.cno;
多表连接则是两两连接,不再多说
嵌套查询
嵌套查询可以根据查询条件分别为相关子查询和不相关子查询
首先看不相关子查询
查询与“刘晨”在同一个系里学习的学生
select *
from student
where sdept in(
secect sdept
from student
where sname = '刘晨'
);
可以看到这里的子查询条件并不依赖于父查询
然后看相关子查询
找出每个学生超过他自己选修课程平均成绩的课程号
select sno cno
from sc x
where grage >=(
select avg(grage)
from sc y
where x.sno = y.sno
);
带有all或者any谓词的子查询
ANY 某一个
ALL 全部
查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄
select sname sage
from student
where sdept <> 'CS' and
sage < any(select sage
from student
where sdept ='CS');
另外还有 exists 谓词查询
集合查询
三大动词
union intersect except 并 交 差
重要题目!!
查询既选修了课程1又选修了课程2的学生
解法1
select sno
from student
where cno = '1' intersect
select sno
from student
where cno = '2';
解法2
select sno
from student
where cno = '1' and sno in(
select sno
from student
where cno = '2'
);
不可用where是因为: 不满足条件是
where cno = ‘1’ and cno = ‘2’
不可能这个条件被同时满足