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 命令
--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.查询得到结果集,可以使用子查询返回一张虚拟表
--查询班级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)