SQL子查询

关联子查询和非关联子查询

子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做非关联子查询。

如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为关联子查询。

eg:

非关联子查询:

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。

eg:

查询出场过的球员都有哪些,并且显示他们的姓名、球员 ID 和球队 ID。在这个统计中,是否出场是通过 player_score 这张表中的球员出场表现来统计的,如果某个球员在 player_score 中有出场记录则代表他出场过。

SELECT play_id,team_id,player_name FROM player WHERE EXISTS (SELECT player_id FROM play_score WHERE player.player_id = player_score.player_id);

NOT EXISTS 就是不存在的意思,我们也可以通过 NOT EXISTS 查询不存在于 player_score 表中的球员信息.

 

集合比较子查询

集合比较子查询的作用是与另一个查询结果集进行比较。

操作符:

IN     判断是否在集合中

ANY   需要与比较操作符一起使用,与子查询返回的任何值做比较  (集合里的最小值)

ALL     需要与比较操作符一起使用,与子查询返回的任何值做比较  (集合里的最大值)

SOME  功能同ANY

 

eg:

查询出场过的球员都有哪些:

SELECT player_id, team_id, player_name FROM player WHERE player_id IN(SELECT player_id FROM play_score WHERE player.player_id = player_score.player_id);

IN 和 EXISTS的区别


SELECT * FROM A WHERE cc IN (SELECT cc FROM B);


SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)

 

IN表是外边和内表进行hash连接,是先执行子查询。
EXISTS是对外表进行循环,然后在内表进行查询。

 

in 判断是否在集合中  exists 判断是否存在,两者的差异性导致调用顺序不同。

如果表 A 比表 B 大,那么 IN 子查询的效率要比 EXIST 子查询效率高;如果表 A 比表 B 小,那么使用 EXISTS 子查询效率会更高。

 

ANY 和 ALL

eg :

查询球员表中,比印第安纳步行者(对应的 team_id 为 1002)中任意一个球员身高高的球员信息,并且输出他们的球员 ID、球员姓名和球员身高。

SELECT player_id, player_name, height FROM player WHERE height > ANY(SELECT height FROM player WHERE team_id = 1002);

查询比印第安纳步行者(对应的 team_id 为 1002)中所有球员身高都高的球员的信息:
SELECT play_id,player_name, height FROM player WHERE height < ALL (SELECT height FROM player WHERE team_id = 1002);

 

 

将子查询作为计算字段

子查询也可以作为主查询的计算字段:

eg:查询每个球队的球员数:

SELECT team_name, (SELECT count(*) FROM player WHERE player.team_id = team.team_id) AS player_num FROM team;

 

 

 

 

上一篇:携程持久化KV存储挑战Redis,狂省90%成本……


下一篇:hostapd、/dev/random、/dev/urandom