• 子查询


    我的理解:

    子查询通常拿来和联合以及分类比较。如果查询条件涉及到了其他的表,就可以使用联合,也可以使用子查询。联合通常是在联合条件为某列和另一列相等的情况下比较方便,通常和group by子句连用。

    子查询是在外面查询一个表,在子查询里查询另一个表,且这两个表之间存在某种联系使得子查询被连接到外部查询中。

    1.select语句中的子查询

    可以将子查询作为SELECT查询内返回一个值的表达式,就像返回单个列一样。但是在一个表达式中子查询必须只返回一个记录,称为标量子查询。

    select category,Category.CategoryId,max(dvdprice) from films inner join Category on Category.CategoryId=films.CategoryId group by Category.CategoryId,category;     --group by 是针对聚合函数的。并且Category.CategoryId,category都要在group by 子句中
    select category,Category.CategoryId,(select max(dvdprice) from films where films.CategoryId=Category.CategoryId) from Category;   --利用子查询,和前面的功能一样。选出每类电影里面dvd价格最高的电影价位。

    说明:满足films.CategoryId=Category.Categoryid条件的电影有很多,因而会返回多个yearreleased值,但是最大值只会返回一个。

    通过where子句,这个子查询被连接到外部的查询中。

    去掉max()函数,执行失败,因为会返回多个值。

     

    2.where子句中的子查询

    select category,max(DVDPrice),films.FilmName from Category inner join films on films.CategoryId=Category.CategoryId group by category;     --错误,filmname不在group表的列中
    select category,max(DVDPrice),films.FilmName from Category inner join films on films.CategoryId=Category.CategoryId group by category,filmname;  --结果错误,这句话返回的并不是某一类的电影的最低价格,而是一个特定电影类型中一部特定电影的最低价格。必须使用子查询了。                          
    select category,DVDPrice,films.FilmName from Category inner join films on films.CategoryId=Category.CategoryId where films.DVDPrice=(select max(DVDPRICE) from films where films.CategoryId=Category.CategoryId);   
     --这样写就不会返回null的值,因为没有办法判断null是否等于null。  
     --inner join 只是表示联合的条件,后面子查询中的where联系了外部查询,实现了按categoryid来分类。
     --需要找到一种类型电影中的最低的价格,然后返回价格等于最低价格的电影名以及其价格。

    比较和上面结果的区别,这里没有返回null。因为where过滤条件里面有一个films.DVDPrice=?,null的等值判断返回的是0.

     select max(dvdprice) from films where dvdprice<(select max(DVDPrice) from films);     --寻找某一列的第2大的数

    3.子查询中的运算符

     (1)in运算符

    select firstname,lastname,year(dateofbirth) from MemberDetails inner join films on year(DateOfBirth)=YearReleased group by firstname,lastname,year(dateofbirth);    
     --这里的group by 子句不能省,否则会返回所有year(DateOfBirth)=YearReleased的记录,如果相同发行年份的电影有多部,则会用相同的人去匹配这个年份,出现重复记录。利用group by 子句保证了记录的唯一性。
     select firstname,lastname,year(dateofbirth) from MemberDetails where year(dateofbirth) in (select yearreleased from films);
    select firstname,lastname,year(dateofbirth) from MemberDetails where year(dateofbirth) not in (select yearreleased from films);    --当所查找的记录不在一个类里面的时候,用联合则非常困难。
    select firstname,lastname,year(dateofbirth) from MemberDetails left out join films on year(DateOfBirth)=YearReleased where yearreleased is null;     --这句话和上面的效果一样。外部联合返回了一切年份相等以及不相等的memberdetails中的列,然后用where子句过滤掉了相等发行年份的记录。

    (2)ANY,SOME,ALL

    --首先any和some是一致的
    select firstname,lastname,year(dateofbirth) from MemberDetails where  year(dateofbirth)=any(select yearreleased from films);    --和前面的in一样
    select firstname,lastname,year(dateofbirth) from MemberDetails where  year(dateofbirth) <> any(select yearreleased from films);   --和前面的not in 一样
    select firstname,lastname,year(dateofbirth) from MemberDetails where  year(dateofbirth)<any(select yearreleased from films);     --也可以在any之前使用其他运算符
    
    select memberid from memberdetails where memberid<all(select filmid from films where filmid>99);   --where 2<all(3,9,5)为true,where 7<all(3,9,5)为false

    (3)exists运算符

    select Category from Category where exists(select * from films where Category.Categoryid=films.CategoryId and rating>3 and (select count(CategoryId) from FavCategory where FavCategory.CategoryId=Category.CategoryId)>=3);
    --是否存在一个电影类别,有3个以上的成员喜欢它,并且该类里面至少有一部电影的评分在3以上,如果有,则返回该类别。

    4.having子句中使用子查询

    select city from MemberDetails group by city having avg(year(dateofbirth))>(select avg(year(dateofbirth)) from MemberDetails);  --找出这样一个城市,这个城市所有人口的平均出生年龄是比整个memberdetails表里面的人口的平均年龄小的。

    5.相关子查询

     指访问外部查询的子查询。相关变量是指付给表的别名。

    select filmname,rating,dvdprice,category from films as fm1 inner join category as c1 on ca.categoryid=fm1.categoryid where fm1.dvdprice=
    (slect min(dvdprice) from films as fm2 where fm2.dvdprice is not null and fm1.categoryid=fm2.categoryid and fm2.rating=
    (select max()fm2.rating) from films as fm3 where fm3.dvdprice is not null and fm2.categoryid=fm3.categoryid group by fm3.categoryid)
    group by fm2.categoryid)
    order by fm1.categoryid;

    6.其他子句中的子查询

    (1)insert子句

    insert into favcategory select 7,memberid from memberdetails where lastname='Hawthorn';

    (2)update子句

    update films set dvdprice=(select max(dvdprice) from films);

    (3)delete from子句

  • 相关阅读:
    [20220314]利用vim下使用gdb进行各种进制转换插件.txt
    [20220228]enq TX allocate ITL entry的测试3.txt
    php输出json时,如何将空数组转为空对象
    C# String 前面不足位数补零的方法
    Gitlab权限管理
    Sql Server 存储乱码,出现问号?显示
    【填坑】处理:java: 错误: 不支持发行版本 5
    运行从sapui5官网下载代码的方法
    通过Fiori app的名字,找到sewg里的project
    SAPUI5 Fiori课程计划
  • 原文地址:https://www.cnblogs.com/wy1290939507/p/4538756.html
Copyright © 2020-2023  润新知