子查询

子查询(subquery),就是嵌套在其他查询中的查询。

举例:订单存储在两个表中。每个订单包含订单编号、客户
ID、订单日期,在Orders表中存储为一行。各订单的物品存储在相关的OrderItems表中。Orders表不存储顾客信息,只存储顾客ID。顾客的实际信息存储在Customers表中。现在需要列出订购物品RGAN01的所有顾客

语句:SELECT cust_id FROM Orders WHERE order_num IN (SELECT order_num FROM OrderItems WHERE prod_id = ‘RGAN01’);

在SELECT语句中,子查询总是从内向外处理。所以上述语句中,先执行了括号里面的子句,然后再用子查询中返回的结果作为外面语句的查询条件。

语句:SELECT cust_name, cust_contact FROM Customers
WHERE cust_id IN (SELECT cust_id FROM Order WHERE order_num IN (SELECT order_num FROM OrderItems WHERE prod_id = ‘RGAN01’));

为了执行上述SELECT语句,必须执行三条SELECT语句。最里边的子查询返回订单号列表,此列表用于其外面的子查询的WHERE子句。外面的子查询返回顾客ID列表,此顾客ID列表用于最外层查询的WHERE子句。最外层查询返回所需的数据。

可见,对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。

注意:作为子查询的SELECT语句只能查询单个列。企图检索多个列将返回错误

子查询作为计算字段

需要显示Customers表中每个顾客的订单总数。订单与相应的顾客ID存储在Orders表中。

执行这个操作,要遵循下面的步骤:

    1. 从Customers表中检索顾客列表;
    2. 对于检索出的每个顾客,统计其在Orders表中的订单数目。
    语句:SELECT cust_name, cust_state, (SELECT COUNT(*)
     FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name;输出结果:
     cust_name cust_state ordersFun4All IN 1
     Fun4All AZ 1
     Kids Place OH 0
     The Toy Store IL 1
     Village Toys MI 2

    这条SELECT语句对Customers表中每个顾客返回三列:cust_name、cust_state和orders。orders是一个计算字段,它是由圆括号中的子查询建立的。该子查询对检索出的每个顾客执行一次。在此例中,该子查询执行了5次,因为检索出了5个顾客。
    子查询中的WHERE子句与前面使用的WHERE子句稍有不同,因为它使用了完全限定列名,而不只是列名(cust_id)。它指定表名和列名(Orders.cust_id和Customers.cust_id)。下面的WHERE子句告诉SQL,比较Orders表中的cust_id和当前正从Customers表中检索的cust_id。使用不同的表时,必须要指定两表关联的条件,条件中要指定是哪个表的字段。