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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,176评论 0 9
  • 茫茫大漠,漫漫黄沙,天地就是一熔炉,而我孑然一人陷在其中。三天两夜的敦煌之行已结束,但是这个画面偶尔在心间飘过。 ...
    黑页饮马槽阅读 1,052评论 11 7
  • 文/西子 10天一本书,精读《活法》第七天,因果报应。 这都是命啊! 你听到这句话的时候,场景一般是什么?我所接触...
    西子Fang阅读 210评论 0 0
  • 英雄联盟,对我来说,是一款充满回忆的游戏。 当年大学年轻的时候,我的一手卡特琳娜QWER操作猛如虎,由于当时操作潇...
    一个豆腐阅读 319评论 0 0
  • 本周末老公要奔赴上海出差,我呢,作为优秀员工冠军,被奖励的家庭旅游基金尚未消费,于是我们两个人快速设计了个最优方案...
    完颜洋洋阅读 323评论 0 0