数据库学习笔记和小练习(3)数据查询

来源:互联网 发布:visio中文版mac下载 编辑:程序博客网 时间:2024/06/01 19:32

本文章参考自《数据库系统概论》

数据查询是数据库的核心操作,SQL提供了select语句进行数据查询。

最核心的是select...from...

(我们要从哪里,哪张表或者视图中取出什么即哪些列)

where子句还可以有条件表达式,先符合条件再选。

group by子句和having短语可以分组,通常在每组中作用聚集函数

最后才是order by子句,确定是升序还是降序。


1.单表查询

select Sname,Snofrom student;
查询全体学生的姓名和学号。

select * from student;

查询全体学生的所有属性。

select Sname,2016-Sagefrom student;

查询的第二列是一个算数表达式(显示出来的就是生日)

select Sname,'year of birth: ',2016-Sage as birthday,lower(Sdept)from student;
查询的表达式可以使算术表达式,还可以还是函数和字符串常量等。

这里birthday是别名 as 可省略。

select distinct Snofrom sc;
加上distinct后会去除重复值的行,默认是all即不去除重复值的行。

select distinct Snofrom scwhere Grade<60;
列出有课程不及格的学生(因为使用了distinct所以哪怕学生有多门考试不及格也只列一次)

这里在where子句使用了查询条件。

select Sname,Sdept,Sagefrom studentwhere Sage not between 20 and 23;

列出了年龄不再20~23岁之间的学生的信息

select Sname,Ssexfrom studentwhere Sdept not in('CS','MA','IS');

查询既不是cs,ma也不是is学生的信息

关于字符匹配:

不使用通配符的时候,like 和 = 是一样的功能

使用通配符的时候:  %匹配任意长度字符串        _匹配单个字符

select Sname from studentwhere Sname like '欧阳_';

查询姓欧阳且全名为三个汉字的学生的姓名

(数据库字符集为ascll时一个汉字需要两个_,当字符集为gbk时只需要一个_)

select Sname,Sno,Ssexfrom studentwhere Sname not like '刘%';

查询所有不姓刘的学生的信息。

select *from coursewhere Cname like 'DB\_%i__'ESCAPE'\';

查询以DB_开头,且倒数第三个字符为i的课程的信息

(escape'\'表名前面字符串匹配表达式中的\后面的字符是转义字符)

判断空值和非空值:

where Grade is null;where Grade is not null;

多重条件查询:

where Sdept='CS' and Sage<20;where Sdept='CS' or Sdept='MA' or Sdept='IS';

order by 子句:

select *from Studentorder by Sdept,Sage desc;

查询的结果按所在系的系号升序排列,同一系中的学生按照年龄降序排列

(1.升序降序只修饰一列    2列的书写顺序就是排序优先级,第一优先级相等时,才进行下一优先级比较)

聚集函数:count , sum , avg , max , min

select count(distinct Sno)from sc;

查询选修了课程的学生人数(distinct因为可能有学生选了多门课,避免重复计算)

(当聚集函数遇到空值时,除了count(*)外,都跳过不处理)

(where子句不使用聚集函数,应该是having子句中使用)

group by子句:

将查询结果按某一列或多列的值分组,值相等的为一组。

(分组后聚集函数将作用于每一组,即每个组都有一个函数值)

select Snofrom scgroup by Snohaving count(*) > 3;
having短语给出了选择组的条件,只有满足条件,即学生选课超过三门,才会被选出来。

(having短语作用于组,从中选择出满足条件的组)


2.连接查询:
连接查询的where子句中用来连接两个表的条件称为连接条件和连接谓词,当连接运算符为=时,称为等值连接,使用其他运算符称为非等值连接。

select student.*,sc.*from student,scwhere student.Sno = sc.Sno;
两个表通过公共属性连接起来,因为这里公共属性名相同,所以需要加表明前缀。

(若在等值连接中把目标列的重复属性列去掉则为自然连接)


也可以是一个表与其自己进行连接,称为表的自身连接。

(可以在from子句中给表取两个别名,用以区分使用)


外链接:

把不符合条件的元祖也输出,属性值填空(称为悬浮元祖)

select student.Sno.Sname,Ssex,Sage,Sdept.Cno.Gradefrom student left outer join sc on(student.Sno=sc.Sno);

这是左外连接,就是列出左边关系中的所有元祖,右外连接就是列出右边关系中的所有元祖。


3.嵌套查询:
一个select-from-wher语句称为一个查询快,将一个查询块嵌套在另一个查询块的wher子句或having子句的条件中的查询称为嵌套查询。

(子查询的select语句不能使用order by子句)

不相关子查询:查询条件不依赖父查询

select Sno,Sname,Sdeptfrom studentwhere Sdept in(select Sdeptfrom studentwhere Sname='刘晨');

根据刘晨找到所在系,再找到这个系的学生

select S1.Sno,S1.Sname,S1.Sdeptfrom student S1,student S2where S1.Sdept=S2.Sdept and S2.Sname='刘晨';

还可以如上用自身连接来完成。(可视化思维)


如果子查询的查询条件依赖于父查询,这类子查询称为相关子查询

select Sno,Cnofrom sc xwhere Grade >= (select avg(Grade)from sc ywhere y.Sno=x.Sno);

找出每个学生超过他自己选修课程平均成绩的课程号

4 集合查询:

集合操作主要包裹并操作union 交操作intersect 差操作except

union将多个查询结果合并起来时会自动去除重复的元祖,要保留用union all





0 0