文章目录

  • 从例子引入
  • 小结
  • 用子查询创建计算字段(注意完全限定列名)
  • 小结


子查询这节有点难度了

子查询其实就是嵌套的查询,嵌套的select语句,把多个有序的查询任务嵌套为一个select语句,逐步完成,从内到外执行

之前遇到的select语句查询都是简单的查询,即只需要单个select语句

mysql select distinct嵌套 select语句嵌套_子查询


mysql select distinct嵌套 select语句嵌套_字段_02


以前还不支持子查询呢

子查询主要用在关系表中,即数据库的多个表之间有关系,比如一个表存订单,列有顾客id,订单号;一个表存顾客信息,存了顾客联系方式,名字等;一个表存一个订单的所有物品和数量信息。

下面通过例子来讲解子查询:

从例子引入

mysql select distinct嵌套 select语句嵌套_字段_03


要查订购了产品rgan01的所有顾客的信息,那就要三次select查询:

  • 先在orderitems表中查出订购了这个产品的订单号
select order_num
from OrderItems
where prod_id = 'RGAN01';

mysql select distinct嵌套 select语句嵌套_嵌套_04

  • 然后根据订单号再去在orders表中查这些订单号的顾客编号
select cust_id
from orders
where order_num in (20007, 20008);

mysql select distinct嵌套 select语句嵌套_子查询_05

  • 再去customers根据顾客编号查询出想要的顾客信息
select cust_name, cust_contact
from customers
where cust_id in (1000000004, 1000000005);

mysql select distinct嵌套 select语句嵌套_子查询_06

但是我们这么写很不方便,实际不可能这么写的,因为后一个操作依赖于前一个的结果,所以就要用到子查询,即嵌套查询,把三个查询整合为一个整体:

select cust_name, cust_contact
from customers
where cust_id in (select cust_id
				  from orders
                  where order_num in (select order_num
									  from OrderItems
									  where prod_id = 'RGAN01'));

mysql select distinct嵌套 select语句嵌套_子查询_07


mysql select distinct嵌套 select语句嵌套_字段_08


注意写这种嵌套查询一定要用缩进和分行,即代码格式化,增加可阅读性和维护性。这样代码的层次和结构分明,不易出错。

mysql select distinct嵌套 select语句嵌套_嵌套_09

小结

  • 嵌套层数虽然没有限制,但不要嵌套太多
  • 嵌套其实效率并不高,还有更好的办法
  • 一定注意:每一个子查询只可以查一列数据!!!!上面的例子中都是1列
  • 注意分行和缩进的格式

用子查询创建计算字段(注意完全限定列名)

mysql select distinct嵌套 select语句嵌套_子查询_10


这种需求是很可能发生的,每一个顾客的订单总数,不是已经有的列,需要计算,所以需要创建一个计算字段并用as关键字起个别名

就是统计每一个顾客id在orders表中的出现行数。

如果统计一个特定顾客的订单总数,很简单:

select count(*) as cust_order_num
from orders
where cust_id = 1000000001;

cust_order_num是一个计算字段

mysql select distinct嵌套 select语句嵌套_子查询_11

如果统计每一个顾客的订单总数,就要写一个子查询

select 
cust_name, 
cust_state, 
(select count(*) 
from orders
where orders.cust_id = customers.cust_id) as cust_order_num
from Customers
order by cust_name;

cust_order_num是由圆括号的子查询创建的计算字段。

这个子查询对检索到的每一个顾客都使用一次子查询

mysql select distinct嵌套 select语句嵌套_嵌套_12


如果不用完全限定列名:

select 
cust_name, 
cust_state, 
(select count(*) 
from orders
where cust_id = cust_id) as cust_order_num
from Customers
order by cust_name;

mysql select distinct嵌套 select语句嵌套_子查询_13


结果出错了,这是因为DBMS认为orders表中的cust_id等于cust_id,自己当然等于自己,所以每一个顾客都输出了5,即订单表orders的总行数

小结

  • 完全限定列名指定了表明和列名,在可能混淆的时候必须使用完全限定列名,如果DBMS不知道到底是哪个就会出错。
  • 这种子查询一般用在where的in操作符中,也不一定,也可以用来创建select中的计算字段。