十五、联结表
关系表
把信息分解为多个表,一类数据一个表,比如vendors表的主键又称为products表的外键,它将两个表联结在一起。
创建联结
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id=products.vend_id
ORDER BY vend_name, prod_name;
- 在引用的列可能出现二义性时,必须使用完全限定列名,用一个点分隔的表名和列名。
- 在联结两个表时,我们是将第一个表中的每一行与第二个表中的每一行匹配。要保证所有联结都有
WHERE
子句。
内部联结
目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内部联结。
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id=products.vend_id;
十四章中的例子
可以改写为:
SELECT cust_name, cust_contact
FROM customers, orders, orderitems
WHERE customers.cuts_id=orders.cust_id
AND orders.order_num=orderitems.order_num
AND prod_id='TNT2';
十六、创建高级联结
表别名
有时候会在单条语句中多次使用相同的表,为了避免引用的二义性,所以允许创建表别名。
加入我们要找到ID为DTNTR的产品供应商生产的其他物品。
SELECT p1.prod_id, p1.prod_name
FROM products AS p1, products AS p2
WHERE p1.vend_id=p2.vend_id
AND p2.prod_id='DTNTR';
自然联结
自然联结排除多次出现,每个列只返回一次,我们接触到的每个内部联结都是自然联结。
外部联结
许多联结将一个表中的行与另一个表中的行相关联。但有时候会需要包含没有关联行的那些行。比如:列出所有产品以及订购数量,包括没有人订购的产品。
这种联结称为外部联结。
SELECT customers.cust_id, orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;
上述语句中是从左边的表customers中选择所有行,若要从右面的表中选择所有行要用RIGHT OUTER JOIN
带聚集函数的联结
SELECT customers.cust_id,
customers.cust_name,
COUNT(orders.order_num) AS num_ord
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;
GROUP BY customers.cust_id;
也可以使用外部联结,但结果中不会出现未下单的客户。
注意在联结中,必须要提供联结条件,否则会得出笛卡儿积。