SQL进阶-(2)

--表链接Join--sql

--查询全部学生的姓名、年龄及所在班级c#

--使用子查询ssh

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

--使用from多表spa

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

from Student,gradeget

where Student.ClassId=grade.ClassIdast

--使用多表链接  表 inner join 另外的表  on 如何创建关联(可以创建关联的字段通常就是可以建立主外键关系的字段)class

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 命令

--go

--获取六期班学员信息

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

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

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

 

--CREATE  PROC[EDURE]  

--procedure

 

 

--子查询--

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

--子查询作为条件--

--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.查询获得结果集,可使用子查询返回一张虚拟表

--查询班级ID1的全部学员的考试成绩

--1查询出班级ID1的学员的学号

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)