⚠️版本要求:MySQL4.1引入了对子查询的支持,所以要想使用本章描述的mysql必须使用4.1更高的版本。
例:列出订购物品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') );
- 复制代码

虽然子查询一般与IN操作符结合使用,但也可以用于测试等于(=),不等于(<>)
例:显示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;
- 复制代码

SQL强大的功能之一就是可以在数据检索查询的执行中联结。
我们设计两个表,一个供应商表,一个商品表,供应商表的主键标识就是商品表的外键。
这样关系数据可以有效的存储和方便的处理,他的可伸缩性是要远远好于非关系数据库。
可伸缩性
能够不断适应增加的工作量而不失败,设计良好的数据库或应用程序称之为可伸缩性好。
就像上面说的,你把数据分解到多个数据表这是有代价的,如果你想要的数据在多个数据表中你要怎么办呢?
🗯答案就是使用联结。
- SELECT vend_name ,prod_name,prod_price
- FROM vendors,products
- WHERE vendors.vend_id = products.vend_id
- ORDER BY vend_name,prod_name;
- 复制代码

🐼这里要完全限定列名,不然MySQL可处理不了这种充满二义性的WHERE语句。
在联结两个表的时候。实际是将第一个表的每一行,与第二个表的每一行配对,WHERE子句作为过滤条件,他只包含哪些匹配给定条件的行。没有WHERE子句,返回的信息将是特别特别多的呀。
由于没有连接条件的表关系返回的结果为笛卡尔积。检索出的行的数目
目前为止的所有连接都是等值连接,他是基于两个表之间的相等测试。这种连接称为内部联结。其实,这种连接是原有另外一种写法 的。(这种写法可以明确指定连接的类型)
- SELECT vend_name ,prod_name ,prod_price
- FROM vendors INNER JOIN products
- ON vendors.vend_id = products.vend_id;
- 复制代码
- SELECT prod_name ,vend_name ,prod_price ,quantity
- FROM orderitems ,products, vendors
- WHERE products.vend_id = vendors.vend_id
- AND orderitems.prod_id = products.prod_id
- AND order_num = 20005;
- 复制代码

🌂mysql处理联结表是特别浪费性能的,所以我们要仔细,不要联结不必要的表。联结的表越多,性能的下降越厉害。
我们可以把之前的一个SELECT拿出来搞一个一题多解。
- 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') );
- 复制代码
我们试试联结的方法
- SELECT cust_name , cust_contact
- FROM customers , orders, orderitems
- WHERE customers.cust_id = orders.cust_id
- AND orderitems.order_num = orders.order_num
- AND prod_id = 'TNT2';
- 复制代码
