子查询

我的理解:

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

 

posted @ 2015-05-29 16:10  wy1290939507  阅读(231)  评论(0编辑  收藏  举报