SQLServer基础(七)

亡梦爱人 提交于 2020-03-18 11:07:50

 

第八章、子查询
8.1、子查询入门
     子查询包含两种类型:一种,只返回一个单值,相当于一个拥有返回值的函数
                         另一种,返回一列值得子查询,相当于一个临时的数据表。
8.1.1、单值子查询
     与普通select没区别,唯一限制是子查询返回值必须只有一行记录,只有一个列:标量子查询。
     select 1 as F1,2,(select min(FYearPublished) from T_book),(select max(FYearPublished) from T_book) as F4
8.1.2、列值子查询
     可以返回一个多行多列的结果集:表子查询。
     select T_Reader.FName,t2.FYearPublished,t2.FName from T_Reader,(select * from T_BOOK where FYearpublished<1800) t2
8.2、select列表中的标量子查询
     标量子查询完全可以返回随当前查询记录而变化的值。
     Attention:这里的子查询与前边讲的有所不同,前面的子查询没有依赖于外部查询中的字段,也就是可以直接单独执行,但是这里依赖于外部查询中的字段,这里子查询无法单独执行。
     select FId,FName,
          ( select max(FyearPublished) from T_Book where T_Book.FCategoryId=T_Category.FId )
     from T_Category
8.3、where子句中的标量子查询     
     select T_Category.FId , T_Book.FName , T_Book.FYearPublished
          from T_Category Inner Join T_Book  On T_Category.FId = T_Book.FCategoryId
          where T_Book.FYearPublished = 
               (
               select min (T_Book.FYearPublished) from T_Book  where  T_Book.FCategoryId = T_Category.FId
               )
8.4、集合运算符与子查询
     运算符:IN、Any、All、Exists
8.4.1、In运算符
     In运算符可以用来匹配一个固定集合中的某一项,in后面也可以是子查询,不过必须与相匹配的的对应。
     select * from T_Book where FYearPublished in (2001,2003,2005)
8.4.2、Any与Some
     any必须与其他的比较运算符共同使用,而且必须将比较运算符放在any关键字之前,所比较的值需要匹配子查询中的任意一个值。"=any" 等价于 In 运算符,而"<>Any"则等价于Not In运算符。
     select * from T_Reader where FYearPublished = Any 
          ( select FYearPublished from T_Book )
     any包括<,>,>=,<=等比较运算符的共同使用。
     select * from T_Book where FYearPublished < Any 
          ( select FYearOfBirth from T_Reader )
     Attention:Any不能与固定的集合匹配, 如 > any (2001,2003)
8.4.3、All运算符
     All运算符要求比较的值需要匹配子查询中的所有值。All运算符不能单独使用,必须和比较运算符共同使用。并且All不能与固定的集合相匹配。
     Attention:当使用All时,如果带匹配的集合为空,也就是子查询没有返回任何数据的时候,不论与什么比较运算符搭配使用All的返回值将永远是true。
     select  * from T_Book 
          where FYearPublished < All ( select FYearOfJoin from T_Reader )
8.4.4、Exsits 运算符
     Exists运算符是单目运算符,它不与列匹配,因此它也不要求待匹配的集合石单列。Exist运算符用来检查每一行是否匹配子查询,可以认为Exists就是用来测试子查询的结果是否为空,如果结果集为空,则匹配结果为false,否则匹配结果为true。
     select * from T_Book 
          where exists ( select * from T_Reader where FProvince='ShanDong' )
     使用Exists运算符要么就是匹配返回表中所有数据,要么就是不匹配不返回任何数据,好像Exists运算符没有什么意义,其实exists运算符真正意义只有和相关子查询一起使用才更有意义。
8.5、其他类型SQL语句中的子查询应用
     子查询也可用在insert 、update、delete中。
8.5.1、子查询在Insert中应用
     如果复制一个表的数据到另一个表,除了insert...values还有一种就是insert...select。
     Insert into T_Reader2(FId,FName) select FId,FName from T_Reader
     与此同时,Insert...select还可以将插入的数据进行处理以后再插入。如下,采用case函数来实现对数据插入前的处理。
     insert into T_ReaderFavorite2(FCategoryId,FReaderId)
          select FCategoryId,
               (CASE
                    when FReaderId<=10 then FReaderId  Else FReader - FCategoryId
               End)
          from  T_ReaderFavorite
     因为可以对数据进行处理,因此insert...select不受同结构表间的数据插入。
8.5.2、子查询在Update...set语句中的应用
     主要是update与where相结合的使用。
     update T_Book b1 set bi.FYearPubulished = 2005 
          where (select count(*) from T_Book b2 where b1.FCategoryId=b2.FcategoryId)>3
8.5.3、子查询在delete中使用
     子查询delete中唯一可以应用的位置就是where子句。
     delete from T_Book b1 where
          (select count(*) from T_Book b2 where b1.FCategoryId=b2.FCategoryId)>3
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!