15.1.子查询的概念
子查询就是指一个“正常查询语句”中的某个部分(比如select部分,from部分, where部分)又出现了查询的一种查询形式,比如:
select * from XX表名 where price >= (一个子查询语句);
此时,子查询所在上“上层查询”,就被称为主查询。
也可以这么说:子查询是为主查询的某个部分提供某种数据的查询。比如一个商品表中的平均价(需要计算、统计的)
上一条语句中,括号中的子查询语句如果查出的是一个“某个数值”(比如3000),则其就相当于:
15.2.标量子查询
含义:
标量子查询就是指子查询的结果是“单个值”(一行一列)的查询。
使用:
标量子查询通常用在where子句中,作为主查询的一个条件判断的数据。
本质上,标量子查询的结果,就可以直接当做“一个值”来使用。
找出产品表中价格大于北京产地的产品平均价的所有产品。
-- 子查询:
找出产品表中价格大于北京产地的产品平均价的所有产品。
select * from product where price > (
#查询出北京产地所有产品的平均价
select avg(price) from product where chandi='北京'
);
课堂练习:找出所有奢侈品!
select * from product where price > (
#找出贵重品的平均价
select avg(price) from product where price > (
#去找出所有商品的平均价
select avg(price) from product
)
);
15.3.列子查询
含义:
列子查询查出的结果为“一列数据”,类似这样:
select pinpai from product where chandi = ‘北京’;
列子查询通常用在where子句的 in 运算符中,代替in运算符中的“字面值”列表数据。
select * from product where chandi in ( '北京', '深圳','天津' )
--如果in中的数据并不方便一个一个列出,但可以通过一个查询得到,就可以使用查询来实现:
select * from product where chandi in ( select chandi from product price > 4000 );
查出出产贵重商品(假设价格超过5000即为贵重商品)的那些产地的所有商品。
select * from product where chandi in(
#找出出产贵重品的那些产地
select chandi from product where price > 5000
);
15.4.行子查询
行子查询查出的结果通常是一行,类似这样:
select pinpai, chandi from product where price=11499;
where salary=10000 and age=18;
-等价于
where (salary,age) = (10000,18);
行子查询的结果通常跟“行构造符”一起,在where条件子句中做为条件数据,类似这样:
where (字段1, 字段2 ) = (行子查询)
或
where row(字段1, 字段2 ) = (行子查询) //含义跟上一行是一样的,即row可以省略
找出跟单价最高的商品同品牌同产地的所有商品。
-- 行子查询
--找出跟单价最高的商品同品牌同产地的所有商品。
--另一个分析思路:
--1,先找出单价最高的商品的品牌和产地
select pinpai, chandi from product where price = (
select max(price) from product--找到商品最高价
)
--2, 然后,在上述“已知”的产地和品牌的情况,找同产地和品牌的“所有商品”
select * from product where row(pinpai, chandi) = (
select pinpai, chandi from product where price = (
select max(price) from product
)
);
15.5.表子查询
当一个子查询查出的结果是“多行多列”的时候,就是表子查询。
表子查询的结果相当于一个表,可以直接当做一个表来使用。
表子查询通常用在主查询的from子句中,作为一个“数据源”。
from (select ... 子查询 ) as tab1
–此时需要给该子查询设置一个别名,类似这样:
查出商品价格大于4000的所有商品的数量和均价
--1先找出价格大于4000的所有商品:
select * from product where price > 4000;
--2将上述查询结果(是多行多列的)当做一个表(表子查询),
--去对这些数据求出总数量和均价
select count(*) as 总数, avg(price) as 平均价 from (
select * from product where price > 4000
) as t;
--当然,本需求,不用子查询,也可以实现,如下:
select count(*) as 总数, avg(price) as 平均价 from product where price>4000;
15.6.有关子查询的特定关键字
15.6.1.in关键字
in关键字在子查询中主要用在列子查询中代替人为手工罗列出来的多个“字面值”数据。
--找出联想品牌的商品都有哪些类别。
select * from product_type where protype_id in(
--#找出联想品牌的所有商品的类别id
select distinct protype_id from product where pinpai = ‘联想’
)
15.6.2.any关键字
any关键字用在比较操作操符的后面,表示查询结果的多个数据中的任一个满足该比较操作符就算满足。
-- any的使用:
--举例:找出在北京生产的但价格比在深圳生产的任一商品贵的商品。
select * from product where chandi = '北京' and price > any(
--#找出在深圳生产的所有产品的价格
select price from product where chandi = '深圳'
);
15.6.3.all关键字
all关键字用在比较操作操符的后面,表示查询结果的多个数据中的所有都满足该比较操作符才算满足。
-- all 的使用:
--示例:找出在北京生产的但价格比在深圳生产的所有商品都贵的商品。
select * from product where chandi = '北京' and price > all(
--#找出在深圳生产的所有产品的价格
select price from product where chandi = '深圳'
);
15.7.exists子查询
where exists ( 任何子查询 )
含义
该子查询如果“有数据”, 则该exists()的结果为“true”, 即相当于 where true (恒真)结果输出全部内容;
该子查询如果“没有数据”,则该exists()的结果为“false”,即相当于where false(恒假),结果一个也不输出;
说明
1,此子查询语句通常需要用到主查询语句中的字段作为查询条件。
-- exists子查询 示例:
--1,查询商品分类名称中带“电”字的所有商品;
select * from product where exists(
select * from product_type where protype_name like '%电%' and product_type.protype_id = product.protype_id
);
--2,查询联想品牌的产品都有哪些分类;
select * from product_type where exists(
select * from product where pinpai = '联想' and product.protype_id = product_type.protype_id
);
特别注意:
通常,有意义exists子查询不能单独执行
对比:之前的4种子查询都可以单独执行