Mysql数据库允许多个查询合并,也就是将某个查询的结果直接作为下个查询的条件进行多次嵌套的做法,举两个例子:
1. 普通查询
假如需要列出订购物品TNT2的所有客户,应该怎样检索?
第一种,分步查询
(1) 检索包含物品TNT2的所有订单的编号。
select order_num from orderitems where prod_id = ‘TNT2’;
±----------+
| order_num |
±----------+
| 20005 |
| 20007 |
±----------+
(2) 检索具有前⼀步骤列出的订单编号的所有客户的ID
select cust_id from orders where order_num IN (20005,20007);
±--------+
| cust_id |
±--------+
| 10001 |
| 10004 |
±--------+
(3) 检索前⼀步骤返回的所有客户ID的客户信息。
select cust_name,cust_contact from customers where cust_id in (10001,10004);
±---------------±-------------+
| cust_name | cust_contact |
±---------------±-------------+
| Coyote Inc. | Y Lee |
| Yosemite Place | Y Sam |
±---------------±-------------+
第二种,嵌套查询
可以把其中的WHERE⼦句转换为⼦查询⽽不是硬编码这些SQL返回的数据:
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 = ‘TNT2’));
±---------------±-------------+
| cust_name | cust_contact |
±---------------±-------------+
| Coyote Inc. | Y Lee |
| Yosemite Place | Y Sam |
±---------------±-------------+
为了执⾏上述SELECT语句,MySQL实际上必须执⾏3条SELECT语句。
最⾥边的⼦查询返回订单号列表,此列表⽤于其外⾯的⼦查询的WHERE⼦句。
外⾯的⼦查询返回客户ID列表,此客户ID列表⽤于最外层查询的WHERE⼦句。
最外层查询确实返回所需的数据。
2. 计算查询
假如需要显示customers表中每个客户的订单总数。订单与相应的客户ID存储在orders表中。
1. 分布查询
(1) 从customers表中检索客户列表。
select cust_id,cust_name from customers ;
±--------±---------------+
| cust_id | cust_name |
±--------±---------------+
| 10001 | Coyote Inc. |
| 10002 | Mouse House |
| 10003 | Wascals |
| 10004 | Yosemite Place |
| 10005 | E Fudd |
±--------±---------------+
(2) 对于检索出的每个客户,统计其在orders表中的订单数⽬。
select count(*) as orders from orders where cust_id = 10001;
±-------+
| orders |
±-------+
| 2 |
±-------+
2. 嵌套查询
select cust_id,cust_name,
(select count(*)
from orders
where orders.cust_id = customers.cust_id) as orders
)
from customers
order by cust_name;
±--------±---------------±-------+
| cust_id | cust_name | orders |
±--------±---------------±-------+
| 10001 | Coyote Inc. | 2 |
| 10005 | E Fudd | 1 |
| 10002 | Mouse House | 0 |
| 10003 | Wascals | 6 |
| 10004 | Yosemite Place | 1 |
±--------±---------------±-------+
这里说明一下,有几个注意点:
1.这里因为orders表和customers表都具有cust_id,所以需要使用 表名.属性 的调用方式来限定关系。
2. 表名就算在数据库内也不能直接,因为需要使用from 表名 之后,语句语法才能知道去哪个表查询,不然会报错,说不存在。比如我直接写select count(*) where orders.cust_id = customers.cust_id,这样子的话orders.cust_id会提示说不存在,因为你没在语句内定义。
3. 这里的嵌套是直接去修改count语句,而不是修改where后面的限定条件。其原因我认为可以从逻辑上考虑,因为cust_id和cust_name都是来自customers表,而主要有差异的是在count上。因为count需要额外使用到orders表的内容,那么在进行搜索的时候让他from orders然后定义相等条件orders.cust_id = customers.cust_id就可以做计算了