购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.1 子查询

工作中的业务问题有时比较复杂,就需要用子查询来进行复杂查询了。那什么是子查询呢?

子查询就是在from子句中直接写SQL查询语句,也就是将多个SQL查询语句嵌套在一起。这个嵌套的SQL查询语句就是子查询。

使用子查询时,可以把子查询看作临时表,也就是子查询的查询结果表,因为这个查询结果表并不是真实存放在数据库中的表,所以把这样的表称为临时表。

使用子查询时,一般需要用as关键字给子查询起个别名,方便在SQL其他地方使用。另外,如果不用as关键字给子查询起别名,那么有时候会报错:“1248-Every derived table must have its own alias”。

通过下面的面试题,我们来学习如何用子查询解决问题。

面试题8:查找成绩排名第二的学生成绩

【题目】

表4.1所示“成绩表”记录了学生选修课程的名称及成绩。现在需要找出语文课中成绩排名第二的学生成绩。如果不存在第二名成绩的学生,那么查询应返回null。

表4.1 成绩表

【解题思路】

可以把问题拆解为以下两步。

(1)找出所有选修了语文课的学生的成绩。

SQL语句的书写方法如下:

(2)在语文课的成绩中,找出排名第二的学生成绩。

①考虑到成绩可能有一样的值,所以使用关键字distinct对成绩进行去重,SQL语句的书写方法如下:

②把第①步的查询结果(最高的成绩)记为a(给子查询用as关键字起个别名叫作a,方便在SQL的其他地方使用),然后找出小于a的所有成绩,SQL语句的书写方法如下:

③在小于a的所有成绩中,最大值就是课程成绩排在第二名的值。

把上述SQL语句合并在一起就是最终答案。需要注意,在条件语句中编写子查询时,不能包含别名。这是因为该子查询会被当作单个值而不是一个表,最终SQL语句如下所示:

查询结果如表4.2所示。

表4.2 语文课中成绩排名第二的学生成绩

【本题考点】

(1)汇总函数(最大值max())的用法。

(2)去掉重复数据关键字distinct的用法。

(3)子查询的用法,子查询经常被当作中间结果的临时表来使用。

嵌套的SQL查询语句用括号括起来,叫作子查询。为了方便使用子查询,一般会用as关键字给子查询起个别名。

子查询还可以结合逻辑运算符in、any、all,从而构建复杂的查询。

4.1.1 in(子查询)

in常用于where子句中,表示查询某个范围内的数据。in和子查询结合在一起的用法是:in(子查询)。

通过下面的面试题,我们来学习如何应用in(子查询)解决实际问题。

面试题9:如何找出多条件的用户

【题目】

表4.3所示的“销售订单表”记录了销售情况,每一条数据表示哪位顾客、哪一天、在哪个交易网点购买了什么产品,购买的数量是多少,以及对应产品的零售价。

表4.3 销售订单表

现在请查找既购买过ProductA产品又购买过ProductB产品,但没有购买ProductC产品的顾客人数。

【解题思路】

需要把满足以下3个条件的顾客查找出来。

(1)购买过ProductA产品的顾客。

(2)购买过ProductB产品的顾客。

(3)没有购买ProductC产品的顾客。

具体步骤如下。

(1)购买过ProductA产品的顾客,可以用in(子查询),SQL语句的书写方法如下:

(2)购买过ProductB产品的顾客,可以用in(子查询),SQL语句的书写方法如下:

(3)没有购买ProductC产品的顾客,可以在in前面加not,表示不在in里面的数据,也就是not in(子查询),SQL语句的书写方法如下:

计算满足条件的顾客人数,把上面3步的SQL语句组合在一起,最终如下:

4.1.2 all(子查询)和any(子查询)

all(子查询)和any(子查询)需要和比较运算符,包括“大于(>)”“小于(<)”“不等于(<>)”等一起使用。

1.all(子查询)

all常用于where子句中,表示要满足all(子查询)里的所有条件。下面通过两个表格:表格A和表格B,来直观地展示如何使用all(子查询),如图4.1所示。

图4.1 all(子查询)案例演示

第一种情况,>all(子查询)。下面的SQL语句表示,表格B中大于all(子查询)中子查询结果的所有数据,如图4.2所示。

第二种情况,<all(子查询)。下面的SQL语句表示,表格B中小于all(子查询)中子查询结果的所有数据,如图4.3所示。

图4.2 查询表格B中大于表格A的最大值的数字

图4.3 查询表格B中小于表格A的最小值的数字

第三种情况,<>all(子查询)。下面的SQL语句表示,表格B中不等于all(子查询)中子查询结果的所有数据。所以,<>all(子查询)的作用等同于not in(子查询),如图4.4所示。

等同于:

图4.4 查询表格B中不等于表格A中数字的数字

2.any(子查询)

any常用于where子句中,表示只需满足ang(子查询)里的任意一个条件就可以。通过刚才的表格A和表格B来演示,如图4.5所示。

第一种情况,>any(子查询)。下面的SQL语句表示,表格B中大于any(子查询)中子查询结果的任意一个数字的数字,等同于表格B中大于表格A中的最小值(2)的数字,如图4.6所示。

图4.5 any(子查询)案例演示

图4.6 查询表格B中大于表格A的最小值的数字

第二种情况,表格B中的数字等于any(子查询)(等同于:in(子查询))中子查询结果的任意一个数字,即父查询的结果集满足存在于子查询的结果集中这个条件,如图4.7所示。

图4.7 查询表格B中等于表格A的值的数字

等同于:

第三种情况,表格B中的数字小于any(子查询)中子查询结果中的任意一个数字,即父查询的结果集满足小于子查询的任意一个值这个条件,则为真。此处案例要求得到的值小于子查询结果集中的最大值,如图4.8所示。

图4.8 查询表格B中小于表格A的最大值 232dqBn/jhwAucgDNJophUIrAxyPVwZy0BEsh7g+SBk0itR39TCwaxuL1KRj3UF0

点击中间区域
呼出菜单
上一章
目录
下一章
×