子查询(极客时间)
子查询
子查询就是嵌套在查询中的查询, 目的是为了进行更复杂的查询, 同时可以理解查询的过程.
子查询也分为两种, 一种是关联子查询, 一种是非关联子查询.
关联子查询与非关联子查询
子查询的划分是依据了子查询是否执行多次来进行划分的.
子查询从数据表中查询数据结果, 如果这个数据结果只执行一次, 之后这个数据结果作为主查询的条件进行执行, 这种就是非关联子查询.
同样, 如果子查询需要执行多次, 即采用循环的方式, 先从外部查询开始, 每次传入子查询进行查询, 之后结果反馈给外部, 这种嵌套方式就是关联子查询.
举个例子, 创建五张表, player表是球员表, team表是球队表, team_score
是球队比赛成绩表, player_score
是球员比赛成绩表, height_grades
是球员身高对应的等级表.
如果仅仅学习的话可以自己创建表, 看完之后自己出题自己来做, 没必要非要上面的表, 如需下载请到 去下载.
select player_name, height from player where height = (select max(height) from player); // 查询身高最高的球员信息
上面的子查询就是非关联子查询, 查询最高身高的子查询仅仅执行了一次, 不依赖于外部查询.
select player_name, height, team_id from player as a where height > (select avg(height) from player as b where a.team_id = b.team_id); // 查询每个球队中大于平均身高的球员信息
这个子查询就是关联子查询了, 因为里面的查询球队队员平均身高依赖于外(主)查询, 需要使用主查询来获取当前队员是哪个球队的.
exists子查询
关联子查询通常也和exists一起使用, exists子查询用来判断条件是否满足, 满足的话为true, 不满足的话为false. 现在想查询出场过的球员有哪些, 这个就需要到player_score中去查询全部的球员id, 有记录表示出场过.
select player_id, team_id, player_name from player where exists (select player_id from player_score where player.player_id = player_score.player_id); // exists的关联条件是写在子查询中的
有exists, 自查就有not exists, 也就是不存在, 与exists是完全相反的结果.
与exists有相同含义的还有in, 这个下面说.
集合比较子查询
集合比较子查询的作用是与另一个查询结果集进行比较, 可以再子查询中使用in, any, all和some操作符.
现在想查询出场过的球员有哪些, 可以这样写:
select player_id, team_id, player_name from player where player_id in (select player_id from player_score where player.player_id = player_score.player_id); // in查询出场过的球员
哪种效率更好取决于查询表于关联表的数据大小, 查询表达, in的效率高, 相反, exists的效率高.
接下来说说any和all, 这两个通常需要使用比较符, 比较符包括了(>)(=)(<)(>=)(<=)(<>)等.
要查询比印第安纳步行者(对应的twam_id是1002)中任何一个球员身高高的球员信息, sql如下
select player_id, player_name, height from player where height > any (select height from player where team_id = 1002); // 主要身高高于子查询中的人一个一个就可以 sql: select player_id, player_name, height from player where height > all (select height from player where team_id = 1002); // 身高高于球员中的任意一个球员的身高, 简单的说就是比球队中身高最高的球员还要高. select p1.* from player p1 where p1.height = (select max(height) from player p2 where p1.team_id = p2.team_id); // 查询每支球队中, 身高最高的球员信息
any和all关键字必须与一个比较操作符在一起使用, 不适用起不到集合比较的作用, any和all就没有任何意义.
子查询作为计算字段
想查询每支球员的球员数
select team_name, (select count(*) from player where player.team_id = team.team_id) as player_num from team;
上一篇: 曾经的六朝古都,怎么沦落成了一座村庄?
下一篇: 对账单月字段按逗号分隔形成多条数据