数据查询功能:sql
Select <目标列名序列( 须要的列 )> from <数据源( 表格 )> [where<检索条件表达式>] [Group by <分组依据列>] [having <组提取条件>] [order by <排序依据列>]
学生表(student)函数
课程表(course)学习
成绩表(sc)spa
1.查询指定的列code
select Sno ,Sname,sdept From Student
2.查询所有列对象
select * from Student
、排序
3.根据已知参数查询ip
select Sname ,'生日',2018 - Sage from Student
4.指定列的别名内存
列名|表达式 [AS] 列别名 或者 列别名=列名|表达式 select Sname ,'生日' as 常量列 ,2018 - Sage as 年份 from Student
5.去除重复列字符串
select distinct Sno from sc
6.查询知足条件的元组
关键字(WHERE)
select Sname from Student Where Sdept ='计算机系'
select Sname,Sage from Student Where Sage <20
select Sname,Sage from Student Where not Sage >=20
经常使用的where的查询条件
7.肯定范围between ....and和not between....and
格式:列名|表达式 [NOT] between 下限值 and 上限值(包括边界值) select Sname,Sage,sdept from Student where Sage between 20 and 23 (where Sage <20 or Sage>23 )
建立图书表:
create table book( Number char(8) primary key, BookName char(20) not null, price real not null, data datetime not null ) go
select *from book where date between '2009/6/1' and '2009/6/30'
日期类型的常量要用单引号引发来,并且年,月,日之间一般用分隔符隔开,经常使用的分隔符有“/”和“-”
8.肯定集合
关键字IN
select Sname ,Ssexn from Student where Sdept(NOT) IN('信息系','数学系','计算机系')
9.字符串匹配
LIKE关键字
LIKE的通用形式: 列名 [NOT] LIKE <匹配串> 通配符: _:匹配任意一个字符; %:匹配0个或多个字符; []:匹配[]当中的任意一个字符 [^]:不匹配[]中的任意一个字符
例如查询姓“张”的学生详细信息
select * from Student Where Sname Like '张%' select * from Student Where Sname Like '[张李刘]%' select * from Student Where Sname Like '张%' OR Sname Like '李%'
查询全部不姓‘王’也不姓‘张’的学生的姓名。
select * from Student Where Sname NOT Like '[王张]%' where Sanme Like '[^王张]%' where Sname NOT LIKE '王%' AND Sname NOT LIKE '张%'
查询姓“王”且名字是2个字的学生的姓名。
select Sname from Student Where Sname like '王_'
查询姓“王”且名字是3个字的学生的姓名。
select Sname from Student Where Sname like '王_ _'
若是但愿系统在比较时可以去掉尾随空格的干扰可使用sql去掉尾随空格的函数:rtrim(列名)
由于系统在存储“王敏”时固定的char为10个空间因此还要在其后面添加6个空格也就是6个字符
改变后的格式:
select Sname From Student Where rtrim (Sname) LIKE '王__'
查询学号的最后一位不是2,3,5的学生的信息
select * from Student where Sno like '%[^235]'
若是要查找的字符串正好含有通配符,就须要使用一个特殊得转义字符
escape('a')表示位于a字符后面的字符不是转义字符
`where fieldl like '%30!%%' Escape '!'` 查询含有30%的字段 `where fieldl like '%!_%' Escape '!'` 包含_的字段
10.涉及NULL的查询
判断某个值是否为null值,不能使用普通的比较运算符(=,!= 等)
判断列值为空:
列名 IS NULL
判断列值为非空:
列名 IS NOT NULL
查询全部非空的考试成绩学生的学号,课程号,和成绩:
select Sno,Cno, From ,Grade from Sc WHERE Grade IS Not NULL
11.多重条件查询
关键字and和or(AND的优先级大于OR)
select Sname FROM Student WHERE Sdept ='计算机系' AND Sage<20
这里由于AND的优先级大于OR要用括号进行区分
select Sname ,Sdept,Sage from Student where (Sdept ='计算机系' OR Sdept='信息系') AND Sage>=20
也能够用IN语句避免优先级关系
select Sname ,Sdept,Sage From Student WHERE Sdept IN('计算机系','信息系') AND Sage >=20
12.对查询的结果进行排序
ORDER BY <列名> [ASC|DESC] [,....n](默认的排序方式为升序排列)
全体学生年龄按升序排列:
select *from From order by sage ASC
选修c02这门课的学生按降序排列:
select Sno ,Grade from SC where cno='c02' order by grade DESC
查询结果让所在系的系名升序排列,同一系的学生按年龄降序排列:(这个地方的使用注意体会!)
select * from Student order by Sdept ASC,Sage DESC
13.使用聚合函数汇总数据
count(*):统计表中元组的个数。 count([distinct]<列名>):统计本列非空列值个数,distinct表示不包括列的重复值。 sum(<列名>):计算列值总和(必须是数值类型) avg(<列名>):计算列值平均值(必须是数值整形) max(<列名>):求列值的最大值 min(<列名>):求列值的最小值
上面的函数中除了count(*)外,其余函数在计算过程当中均忽略NULL再计算(count计算时若是这一行都为null也算一行)
统计学生总人数:select count(*) from Student
统计了选修课程的学生人数:select count (distinct Sno)from SC(注意一个学生能够选择多门课)
统计'9512101'学生的选课门数和考试总成绩:select count(*) as 选课门数,Sum(Grade)as 总成绩 from SC
WHERE Sno ='9512101'
注意:聚合函数不能出如今where字句当中。
例如:select Sname FROM Student where Sage = MAX(Sage)
是错误的写法。
14.对查询结果进行分组的统计
前面所列举的经过聚合函数的例子都是对全表数据进行统计的,有时咱们但愿计算的精度更高一些,好比统计每一个学生的考试平均成绩,而不是全体学生的考试平均成绩,这时就要用到查询语句的分组功能。
关键字:GROUP BY
分组子句跟在where子句的后边,通常形式:
GROUP BY <> [,....] [HAVING <组选择条件>]
注意:分组依据列不能是text,ntext,image,bit类型的列。
使用group by子句
统计每门课程的选课人数,列出课程和选课的人数。
select Cno as 课程号,Count (Sno) as 选课人数 from SC group by Cno
该语句首先对sc表的数据按Cno的值进行分组,全部具备相同Cno值的元组归为一组,而后再对每一组的元组使用count进行计算,求得每一组的学生的人数。
2.统计每一个学生的选课门数和平均成绩
select Sno 学号,count(*) 选课门数,average (Grade) 平均成绩 from sc gropu by Sno
3.统计每一个系的学生人数和平均年龄
select Sno 学号,Count(*) 选课门数 ,avg(Grade) 平均年龄 from Sc group by Sno
总结: 统计哪一列的各类参数就将哪一列进行分组
4.用带where子句的分组,统计每一个系的女生人数和最大年龄。(按列进行分组而后再按组里面的值有选择的进行运算,而不是直接整组运算能够用where进行修饰)
select Sdept ,count(*) 女生人数 from Student where Ssex ='女' group by Sdept
5.按多列进行分组,统计每一个系的男生人数和女生人数,以及男生的最大年龄和女生的的最大年龄,结果按系命的升序排列。
select Sdept ,Ssexn ,Count (*) 人数,max(Sage) 最大年龄 from Student Group by Sdept ,Ssexn Order by Sdept
6.使用having子句
例:查询选修了3门以上学生学号和选课的门数
select Sno ,Count(*) 选课的门数 from sc group BY Sno HAVING COUNT(*)>3
先执行group by对Sno进行分组,而后再用统计函数count对每一组的元组个数进行统计,最后找出大于3的那一组。
例:查询选课门数大于等于4门的学生的平均成绩和选课门数。
select Sno,Avg(Grade) 平均成绩,count(*) 选课门数 from sc Group by Sno having count (*)>=4
总结:
建议将全部应该分组以前进行的搜索条件放在where子句而不是having子句中,这样写的效率更高一些。
查询计算机系和信息系的学生人数
第一种
select Sdept ,Count (*) from Student GROUP BY Sdept having Sdept IN('计算机系','信息系')
第二种
select Sdept ,Count(*) from Student where Sdept in('计算机系','信息系') group by Sdept
很显然第二种的效率更高一些。
可是要注意一点有时候只能用where限定
例:查询每一个系年龄小于等于20岁的学生的人数。
select Sdept ,count(*) from Student where Sage <=20 group by Sdept
注意该语句不能够写成
select Sdept ,count(*) from Student group by Sdept having Sage <=20
这里是由于having是在分组统计以后再进行这是只包含分组依据列(系别和人数)因此没有Sage元素。
15.多表链接查询
1.内链接
内链接是一种经常使用的链接类型,若是两个表的字段知足链接条件,则能够从这两个表里面提取数据并组和成新的记录。
内链接的语法格式:
from 表1 [inner] join 表2 ON <链接条件>
链接条件的通常格式:
[<表名 1.>] [<列名 1>]<比较运算符> [<表名 2.>][<列名 2>]
当比较运算符为等号(=)是时,称为等值链接,其余的称为非等值链接。
例:
查询每一个学生及其选课的详细信息。
select * from Student Inner JOIN sc on Student.Sno=sc.Sno
在写多链接表时有必要将这些重复的列给去掉,方法是在select 子句中直接列出所须要的列名,而不是'*',另外因为多表链接后,在链接生成的表中可能存在列名相同的列,所以为了明确到底须要哪一个列,能够在列名的前面添加表名前缀限制,其格式:表名.列名
去掉上图中的重复列
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade from Student [Inner] JOIN sc on Student.Sno=sc.Sno
例:查询计算机系的学生的修课状况,要求列出学生的名字,所选择课程号和成绩
select Sname ,Cno ,Grade FROM Student JOIN sc ON Sudent .Sno =sc.Sno where Sdept ='计算机系'
能够为表提供别名,其格式以下:
from <源表名> [as] <表别名>
为表指定别名能够简化表的书写,并且在有些链接查询中要求必须指定别名。
select Sname ,Cno,Grade From Student S join sc
这里要注意的是当你为表指定了别名在查询语句的其余地方,全部用到表民的地方都要使用别名,而不能在使用原表名。
例:查询信息系选修了计算机文化学课程的学生的信息,要求列出学生的姓名,课程名和成绩。
select Sname ,Cname,Grade FROM Student s jOIN sc ON s.Sno=sc.Sno join course c ON c.Cno=SC.Cno where Sdept ='信息系' AND Cname='计算机文化学'
查询全部选修了VB课程的学生状况,列出学生的姓名和所在的系。
select Sname,Sdept From Student S JOIN sc ON S.Sno=sc.Sno JOIN course c ON c.Cno=sc.Cno where Sdept ='VB'
注意:由于原本所须要的数据与sc表无关可是Student和Course没有能够进行链接的元素,因此这是须要引入sc表进行链接。
2.自链接
自链接是一种特殊的内链接,相互链接的表在物理表上为同一张表,但在逻辑上将其当作两张表。from 表1 T1
---在内存中生成表名为T1的表join 表1 T2
---在内存中生成表名为T2的表
所以在自链接时必定要为表取别名。
查询与刘晨在一个系学习的全部学生的姓名和所在系
select S2.Sname ,S2.Sdept from Student S1 join Student S2 on S1.Sdept=S2.Sdept where S1.Sname='刘晨' AND S2.Sname!='刘晨'
----->
分析:
先在s1中找出刘晨这一项数据而后在s2中找出除刘晨外的计算机系全部学生数据最后S1,S2查询结果经过计算机系进行链接
3.外链接
有时候咱们也但愿看到那些不知足元组条件的元组信息,好比查看所有学生的选课的状况既想看到那些课程被选了,哪些课程没有被选择。由于内链接实现首先要有知足链接条件,sc.Cno=course.Cno,若是在sc表中没有人选择课程可是在course中却有,因为不知足上述条件因此查找不出来。
外链接只限制一张表中的数据必须知足链接条件,而另外一张表中的数据能够不知足链接条件。
From 表1 left | right [outer] join 表2 ON <链接条件>
若是是左外链接那么就是限制表2 中的数据必须知足链接条件,而不用管表1中的数据是否知足链接条件,均输出表一中的内容。右链接亦同。
例:查询学生的选课状况,包括选择了课程的学生和没有选择课程的学生,列出学号,姓名,课程号和成绩。
左链接: select Student.Sno,Sname,Cno,Grade from Student left outer join sc on Student.Sno =sc.Sno 右链接: select Student.Sno,Sname ,Cno,Grade From sc right outer join Student ON Student.Sno=SC.Sno
例:查询哪些课程没有人选,列出其课程名。
select Cname FROM Course C left join sc on c.cno=sc.cno where sc.cno is null.
外链接操做中可使用where 子句 ,group by子句等
查询计算机系没有选课的学生,列出学生的姓名和性别。
select Sname,Sdept,Cno,grade from Student S left join sc on S.sno=sc.Sno where Sdept ='计算机系' and Sc.Sno is null.
假设咱们让链接的两个表所有打印:------>
------->
分析:首先进行外链接以student的sno进行链接从student里面拿一个学号与sc里面的学号进行比较相等则链接当student找不到时则链接空值行 链接后的表再进行where筛选。注意此时仍是要当成两个表去看待好比选择一个计算机系且没有选课的(Sno为null)的行就要写成: where Sdept ='计算机系'(sdept惟一只属于student的不用标识) and Sc.Sno(这个须要标识二者都有) is null.
例:统计计算机系每一个学生的选课门数,包括没有选课的学生,结果按选课门数递减排列。
Select s.sno as 学号,count(sc.cno) as 选课门数 from student s left join sc on s.sno=sc.sno where sdept ='计算机系' group by s.sno order by count (sc.sno) desc
首先经过sno进行链接
而后经过计算机系进行过滤
最后经过学号进行分组(须要指定由于学号不惟一)统计
并打印指定的参数列
16.使用TOP限制结果集
在使用select语句时咱们但愿只显示这些结果集中的前几行结果,就可使用top语句。
格式:TOP n [percent] [with ties]
其中:
TOP谓词写在select单词的后边(若是有distinct的话,则在distinct 单词以后),查询列表的前边。