文章目录
- 从例子引入
- 小结
- 用子查询创建计算字段(注意完全限定列名)
- 小结
子查询这节有点难度了
子查询其实就是嵌套的查询,嵌套的select语句,把多个有序的查询任务嵌套为一个select语句,逐步完成,从内到外执行
之前遇到的select语句查询都是简单的查询,即只需要单个select语句
以前还不支持子查询呢
子查询主要用在关系表中,即数据库的多个表之间有关系,比如一个表存订单,列有顾客id,订单号;一个表存顾客信息,存了顾客联系方式,名字等;一个表存一个订单的所有物品和数量信息。
下面通过例子来讲解子查询:
从例子引入
要查订购了产品rgan01的所有顾客的信息,那就要三次select查询:
- 先在orderitems表中查出订购了这个产品的订单号
select order_num
from OrderItems
where prod_id = 'RGAN01';
- 然后根据订单号再去在orders表中查这些订单号的顾客编号
select cust_id
from orders
where order_num in (20007, 20008);
- 再去customers根据顾客编号查询出想要的顾客信息
select cust_name, cust_contact
from customers
where cust_id in (1000000004, 1000000005);
但是我们这么写很不方便,实际不可能这么写的,因为后一个操作依赖于前一个的结果,所以就要用到子查询,即嵌套查询,把三个查询整合为一个整体:
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'));
注意写这种嵌套查询一定要用缩进和分行,即代码格式化,增加可阅读性和维护性。这样代码的层次和结构分明,不易出错。
小结
- 嵌套层数虽然没有限制,但不要嵌套太多
- 嵌套其实效率并不高,还有更好的办法
- 一定注意:每一个子查询只可以查一列数据!!!!上面的例子中都是1列
- 注意分行和缩进的格式
用子查询创建计算字段(注意完全限定列名)
这种需求是很可能发生的,每一个顾客的订单总数,不是已经有的列,需要计算,所以需要创建一个计算字段并用as关键字起个别名
就是统计每一个顾客id在orders表中的出现行数。
如果统计一个特定顾客的订单总数,很简单:
select count(*) as cust_order_num
from orders
where cust_id = 1000000001;
cust_order_num是一个计算字段
如果统计每一个顾客的订单总数,就要写一个子查询
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是由圆括号的子查询创建的计算字段。
这个子查询对检索到的每一个顾客都使用一次子查询
如果不用完全限定列名:
select
cust_name,
cust_state,
(select count(*)
from orders
where cust_id = cust_id) as cust_order_num
from Customers
order by cust_name;
结果出错了,这是因为DBMS认为orders表中的cust_id等于cust_id,自己当然等于自己,所以每一个顾客都输出了5,即订单表orders的总行数
小结
- 完全限定列名指定了表明和列名,在可能混淆的时候必须使用完全限定列名,如果DBMS不知道到底是哪个就会出错。
- 这种子查询一般用在where的in操作符中,也不一定,也可以用来创建select中的计算字段。