前言     




       数据存储到数据库后,如果不对其进行分析和利用,数据是没有价值的。最终用户对数据库中数据进行的操作大多是查询和修改,其中修改操作包括插入、删除和更改数据。SQL提供了功能强大的数据查询和修改的功能。查询,插入和删除。这种东西还是需要多练,现在总结下来,没事儿了可以练练。分享:数据库文件 ,以下举例的语句都是根据这个数据库文件来操作,如有需要,请自行下载练习。


一、选择表中的若干列




1.查询指定列




       select sno,sname from student  (查询全体学生的学号和姓名)


2.查询全部列




       select * from student  (查询全体学生的详细记录)


3.查询结果计算的列




       select 子句中的<目标列名序列>可以是表中存在的属性列,也可以是表达式、常量或者函数。

select sname,year (getdate()) - year(birthdate) from student  (查询学生的年龄)

       其中,getdate() 和year()均是系统提供的函数,getdate()是得到系统的当前日期和时间,year()的作用是得到日期数据中的年的部分。


二、选择表中的若干元组




1.消除取值相同的行




       关系数据库表中不允许存在取值完全相同的元组,但对列进行了选择后,就可能出现了。要消除相同的元组,需要用到distinct关键字。

select sno from sc  (查询选了课程的学号,有相同的元组)   

       select distinct sno from sc  (取消了相同的元组)


2.查询满足条件的元组




1).比较大小

      比较大小常用运算符:=,>,<,>=(大于等于),<=(小于等于),<>(不等于),!=(不等于),!>(不大于),!<(不小于)

select distinct sno from sc where grade < 60  (查询不及格的学生的学号)


2).确定范围

     between....and 和 not between....and

 查询考试成绩在80~90之间的学生学号、课程号和成绩:

     select sno, cno,grade from sc where grade between 80 and 90 

日期类型的数据也可以使用基于范围的查找。查询1991年6月~8月出生的学生的姓名和出生日期:

select sname,birthdate from student where birthdate between '1991/06/01' and '1991/08/31' 


3).确定集合

     in运算符可用于查找属性值在指定集合范围内的元组。格式:列名 [not] in (常量1,常量2........常量n)

查询信息管理系、通信工程系和计算机系学生的姓名和性别:

     select sname,sex,from student where dept in ('信息管理系','通信工程系','计算机系')


4).涉及空值的查询

     空值(null)在数据库中有特殊的含义,它表示当前不确定或未知的值。

     判断列取值为空的子句为: 列名 is null   

     判断列取值不为空的子句为:列名 is not null

查询还没有考试的学生的学号和相应的课程号:

     select sno,cno from sc where grade is null


三、对查询结果进行排序




     升序(asc),从上到下依次增大

     降序(desc) ,从上到下依次减小

 查询修了C002课程的学生的学号及成绩,查询结果按成绩降序排列:

     select sno,grade from sc where cno='C002'order by grade desc


四、使用聚合函数统计数据




1.count(*) 统计表中元组的个数

select count(*) from student  (统计学生总人数)

2.count([distinct] <列名>)统计本列非空列值个数,distinct选项表示去掉列的重复值后再统计。

select count(distinct sno) from sc  (一个学生可以选择多门课,distinct去重)

3.sum(列名):计算列值得和

4.avg(列名):计算列值的平均值

5.max(列名):得到列值的最大值

6.min(列名):得到列值得最小值

注意:上述函数中除count(*)外,其他函数在计算过程中均忽略null值。


五、对数据进行分组统计




       在实际应用中,有时需要对数据进行分组,然后再对每个组进行统计。这种统计就需要分组子句group by ,group by 子句可将计算控制在组这一级。分组的目的是细化聚合函数的作用对象。这个分组看的时候有点费劲,多多练习,多多理解。分组子句跟在where子句后边,它的一般形式为:group by <分组依据列> 


1.group by




统计每门课程的选课人数,列出课程号和选课人数:

      select cno as 课程号,count(sno) as 选课人数 from sc group by cno

      该语句首先对sc表的数据按cno的值进行分组,所有具有相同cno值得元组归为一组,然后再对每一组使用count函数进行计算,求出每组的学生人数。

     注意:group by子句中的分组依据列必须是表中存在的列名,不能使用as子句列别名;带有group by子句的select 语句的查询列表中只能出现分组依据列和聚合函数


2.having




        having子句用于对分组后的统计结果再进行筛选,它的功能与where子句类似,但它用于组而不是单个记录。在having子句中可以使用聚合函数,但在where子句中则不能。having通常与group by子句一起使用。

查询选课门数超过三门的学生的学号和选课门数:

       select sno,count(*) 选课门数 from sc group by sno having count(*)>3

       分析:首先统计出每个学生的选课门数(group by),然后再从统计结果中选出选课门数超过三门的数据(having)

       正确理解where、group by、having子句的作用及执行顺序,对编写正确、高效的查询语句很有帮助。where子句用于筛选from子句中指定的数据源所产生的行数据;group by 子句用于对经where子句筛选后的结果数据进行分组;having子句用于对分组后的统计结果进行筛选。