子查询

  • 版本要求:从MySQL 4.1开始引入了对子查询的支持。
  • 查询:任何SQL语句都是查询。但此术语一般指SELECT语句。
  • 子查询:即嵌套在其他查询中的查询。

利用子查询进行过滤

1
2
3
4
5
6
7
8
-- 列出订购物品TNT2的所有客户
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'));
  • 格式化SQL:包含子查询的SELECT语句难以阅读和调试。把子查询分解为多行并且适当的进行缩进,能极大的简化子查询的使用。
  • 实际使用时由于性能的限制,不能嵌套太多的子查询。
  • 列必须匹配:WHERE子句中使用子查询,应该保证SELECT语句具有与WHERE子句中相同数目的列。

作为计算字段使用子查询

1
2
3
4
5
6
7
8
-- 显示customers表中每个客户的订单总数
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM orders
WHERE orders.cust_id = customers.cust_id) AS orders
FROM customers
ORDER BY cust_name;
  • 相关子查询:涉及外部查询的子查询。

    任何时候只要列名可能有多义性,就必须使用这种语法(表名和列名由一个句点分隔)。

  • 逐渐增加子查询来建立查询:用子查询测试和调试查询很有技巧性,特别是在这些语句的复杂性不断增加的情况下更是如此。

    用子查询建立(和测试)查询的最可靠的方法是逐渐进行,这与MySQL处理他们的方法非常相同:

    首先,建立和测试最内层的查询。然后,用硬编码数据建立和测试外层查询,并且仅在确认它正常后才嵌入子查询。这时,再次测试它。对于要增加的每个查询,重复这些步骤。这样做仅给构造查询增加了一点点时间,但节省了以后(找出查询为什么不正常)的大量时间,并且极大的提高了查询一开始就正常工作的可能性。