SQL进阶2

--表连接Join--

查询所有学生的姓名、年龄及所在班级

使用子查询

 select StudentName,
           DATEDIFF(yyyy,borndate,getdate()),
          (select classname from grade where ClassId=Student.ClassId)
 from Student

使用from多表

 select StudentName,DATEDIFF(yyyy,borndate,getdate()),classname

 from Student,grade

 where Student.ClassId=grade.ClassId

使用多表连接 表 inner join 另外的表 on 如何建立关联(能够建立关联的字段一般就是能够创建主外键关系的字段)

 select StudentName,DATEDIFF(yyyy,borndate,getdate()),classname

 from Student

 join grade on Student.ClassId=grade.ClassId

1.内连接:inner join.找到两个表建立关系的字段值相等的记录,如果字段值不相等,那么就抛弃

查询学生姓名、年龄、班级及成绩

 select Student.StudentName,
           DATEDIFF(YYYY,Student.BornDate,GETDATE()),
           grade.classname,
           Result.StudentResult
 from Student

 inner join grade on Student.ClassId=grade.ClassId

 inner join Result on Student.StudentNo=Result.StudentNo

 where student.ClassId=2

查询每个学员需要参加的考试科目名称

 select Student.StudentNo,Student.StudentName,Subject.SubjectName

 from Student

 inner join Result on Student.StudentNo=Result.StudentNo

 inner join Subject on Result.SubjectId=Subject.SubjectId;



 select Student.StudentNo,Student.StudentName,Subject.SubjectName

 from Student

 inner join Subject on Student.ClassId=Subject.ClassId;



 select * from PhoneType

 inner join PhoneNum on PhoneNum.pTypeId=PhoneType.ptId;

左,右连接

左连接,可以得到左表的所有记录,只不过如果左表的字段的值在右表中找不到相应的关联记录,那么右表中的所有字段会以null值替代

 select * from PhoneType   left join  PhoneNum on PhoneNum.pTypeId=PhoneType.ptId

查询没有参加考试的学员信息

 select * from Student

 left join Result on Student.StudentNo=Result.StudentNo

 where Result.StudentNo is null and Result.SubjectId is null

右连接:

 select * from PhoneType left join PhoneNum on PhoneNum.pTypeId=PhoneType.ptId

交叉连接:

 select * from Student

 cross join grade

做多表连接的建议:

1.先确定字段都来自于那一些表,通过 表.字段 的方式进行确定

2.查看这些表都有那一些关联(可以建立主外键关系的字段),如果没有关联,考虑是否需要使用中间其它表进行关联

3.多表连接后可以得到一个虚拟的表,可以对这个表的所有字段添加where条件

练习1:查询所有英语及格的学生姓名、年龄及成绩

 select Student.StudentName,DATEDIFF(YYYY,Student.BornDate,GETDATE()),Result.StudentResult

 from Student

 inner join Result on Student.StudentNo=Result.StudentNo

 inner join Subject on Result.SubjectId=Subject.SubjectId

 where Subject.SubjectName='office' and Result.StudentResult>=60

练习2:查询所有参加考试的(english分数不为null)学生姓名、年龄及成绩

练习3:查询所有学生(参加和未参加考试)的学生姓名、年龄、成绩,如果没有参加考试显示缺考,如果小于60分显示不及格office

 select Student.StudentName,DATEDIFF(yyyy,student.borndate,getdate()),

 case

  when Result.StudentResult is null then '没有考试'

  when Result.StudentResult>=60 then cast(Result.StudentResult AS CHAR(3))

  else '不及格'  

 end

 from Student

 left join Result on Student.StudentNo=Result.StudentNo

 inner join Subject on Result.SubjectId=Subject.SubjectId

 where Subject.SubjectName='office'
变量的种类--全局变量
go

 insert into grade values('fdasfas')

 select * from Student

 select @@IDENTITY ---它得到的值不是指点上一条语句,而是最近的insert语句的值



go

 select * from Student

 select @@ROWCOUNT



 delete from Student where StudentNo=12433

 select @@ROWCOUNT



go

 @@ERROR 得到最近这一条语句的错误号

 select * from stu --语法错误的错误号得不到

 select @@ERROR --针对于增加删除和修改而言,如果有错误那么错误号一定大于0,如果没有错误那么就一定是0

 update Student set LoginPwd='ss' where StudentNo=1

 update Student set LoginPwd='ss' where StudentNo=1

 select * from Student

go

 select @@ERROR
视图

视图的本质就是一句sql语句--select.它表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上

视图的本质就是一张虚拟表:它的操作与操作表基本一致

视图里面并没有真正存储数据,它存储的是sql语句,当执行视图获取数据的时候,本质就是执行视图中的sql语句去获取数据

 select * from Student

 select * from vw_getstudentResultInfo

通过命令语句创建视图

语法:

go

 create view vw_自定义名称

 as

  select 命令

1.可不可以写多条select查询?只能写一条

2.视图里面只能写select,不能添加任何的update/delete/insert语句

go

--获取六期班学员信息

 if exists(select * from sysobjects where name='vw_getStudentByClassId_6')

 drop view vw_getStudentByClassId_6

go

 create view vw_getStudentByClassId_6

 as

  select top 2 * from Student order by studentname

对视图进行查询

 go

 select * from vw_getStudentByClassId_6 order by studentname

对视图进行修改,可以对视图进行删除增加和修改操作,况且操作会直接影响物理表,所以一般不建立去做这些操作,因为视图的本质目的是为查询

 update vw_getStudentByClassId_6 set classhour = 10, subjectname='c#', classname='111' where subjectid=2

 delete from vw_getStudentByClassId_6 where Studentno=3

视图的增加删除和修改操作只能针对于单个表,如果涉及了多个表的操作,那么将不成功

 select * from vw_getstudentResultInfo

 delete from vw_getstudentResultInfo where Studentno=6

 update vw_getstudentResultInfo set studentresult=55 , subjectname='c#' where Studentno=6
子查询

一个查询里面还包含着另外一个查询

子查询做为条件

1.包含在()里面先执行的查询就是子查询语句,包含子查询的就称为父查询语句

2.引入子查询时,在选择列表中只能指定一个表达式,就是意味着子查询做为条件(有关系运算符)的时候子查询永远不可能出现多列的情况

3.子查询返回的值不止一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的,就意味着如果子查询跟在关系运算符之后,必须保证子查询只返回了单个值,如果真的需要这么做就可以使用关键字 in/not in

查询比林思年龄大的学员信息

4.有子查询的sql语句返回的列只与父查询有关,子查询中的列仅仅是做为条件判断

1.先查询出林思的年龄

 select borndate from Student where StudentName='林思'

返回一行多列值----做为条件永远错误

 select * from Student where BornDate<(select * from Student where StudentName='林思')

返回多行一列值

 select * from Student where BornDate<(select borndate from Student)

查询班级ID《=3的学员信息

 select classid from grade where ClassId<=3

 select StudentNo,StudentName from Student where ClassId not in(select classid from grade where ClassId<=3)

子查询得到某列的值 --用得最少

查询学员是10的学员office考试成绩和考试日期,显示学员姓名

 select (select studentname from student where studentno=10),
           StudentResult,
           ExamDate 
   from Result 
 where StudentNo=10 
     and SubjectId=(select SubjectId from Subject where SubjectName='office')

3.查询得到结果集,可以使用子查询返回一张虚拟表

查询班级ID为1的所有学员的考试成绩

1查询出班级ID为1的学员的学号

 select studentno from Student where ClassId=1

查询指定学号的学员的成绩

 select * from Result where StudentNo in(select studentno from Student where ClassId=1)

分页

 select top 5 * from Student

 select top 5 * from Student where StudentNo not in(select top 5 StudentNo from Student order by StudentNo)

ROW_NUMBER 可以为查询出的每一行返回一个行号,行号类似于标识列,永远不会重复,同是它默认是连续的,这个函数可以为结果集添加一个新列

over说明在那一个字段上进行排序,因为按不同字段排序结果集的显示是不一样的

 select ROW_NUMBER() over(order by studentno) as id,* from Student

如果子查询做为结果集那么必须为其添加别名

 select * from (select ROW_NUMBER() over(order by studentno) as id,* from Student) as temp

 where temp.id>=6 and id<=10

使用Row_number() over(指定排序字段)实现分页,这个函数可以为结果集添加一个新列

 select ROW_NUMBER() over(order by studentno) as id,* from Student

 select * from (select ROW_NUMBER() over(order by studentno) as id,* from Student

 ) as temp where  id>0 and id<=5

查询年龄比“廖杨”大的学员,显示这些学员的信息

 select * from Student where BornDate<(select BornDate from Student where StudentName='廖杨')

查询二期班开设的课程

 select * from Subject where ClassId=(select ClassId from grade where classname='二期班')

查询参加最近一次“office”考试成绩最高分和最低分

 select subjectid from Subject where SubjectName='office'

 select MAX(ExamDate) from Result where SubjectId=(select subjectid from Subject where SubjectName='office')



 select  max(StudentResult),MIN(StudentResult) from Result where SubjectId=

 (select subjectid from Subject where SubjectName='office')

 and ExamDate=

 (select MAX(ExamDate) from Result where SubjectId=

 (select subjectid from Subject where SubjectName='office'))

 select * from Result

 select * from Subject
子查询的分类:

1.独立子查询:单独可以运行的子查询

2.相关子查询:子查询中引用了父查询中的列

查询参加了考试的学员信息

 select distinct StudentNo from Result

 select * from Student where StudentNo in(select distinct StudentNo from Result)



 select * from Student where StudentNo=(select distinct StudentNo from Result where Result.StudentNo=Student.StudentNo)



 select StudentNo from Result where StudentNo=33



 select * from Student where StudentNo=(select StudentNo from Result where StudentNo=33)

你可能感兴趣的:(SQL进阶2)