16.1 使用表别名
第10章中介绍如何使用别名引用被检索的表列。给列起别名的语法如下:
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') AS
vend_title
FROM vendors
ORDER BY vend_name;
给表名起别名
- 缩短SQL语句
- 允许在单条SELECT语句中多次使用相同的表
SELECT cust_name,cust_contact
FROM customers AS c,orders AS o,orderitems AS oi
WHERE c.cust_id=o.cust_id
AND oi.order_num=o.order_num
AND prod_id='TNT2';
表别名只在查询执行中使用,与列别名不一样,表别名不返回客户机。
16.2 使用不同类型的联结
内部联结(等值联结)、自联结、自然联结、外部联结
16.2.1 自联结
子查询
SELECT prod_id prod_name
FROM products
WHERE vend_id=(SELECT vend_id
FROM products
WHERE prod_id='DTNTR');
使用联结的相同查询,能在单条SELECT语句中不止一次引用相同的表
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';
16.2.2 自然联结
自然联结排除多次出现,使每个列只返回一次。
一般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集来完成的
迄今为止,我们建立的每个内部联结都是自然联结
SELECT c.*,o.order_num,o.order_date
oi.prod_id,oi.quantity,oi.item_price
FROM customers AS c,orders AS o,orderitems AS oi
WHERE c.cust_id=o.cust_id
AND oi.order_num=o.order_num
AND prod_id='FB';
16.2.3 外部联结
联结包含了那些在相关表中没有关联行的行
简单内部联结,检索所有客户及其订单。
SELECT customers.cust_id,orders.order_num
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id;
外部联结语法类似。为了检索所有客户,包括那些没有订单的客户
SELECT customers.cust_id,orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;
必须使用RIGHT或LEFT关键字指定包括其所有行的表,LEFT指出的是OUTER JOIN左边的表
16.3 使用带聚集函数的联结
聚集函数用来汇总数据
如果要检索所有客户及每个客户所下的订单数
SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num) AS num_ord
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY customers.cust_id;
SELECT customers.cust_name,
cust_name.cust_id,
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;
使用左外部联结来包含所有客户,甚至包含那些没有下订单的客户。
16.4 使用联结和联结条件
- 注意所使用的联结类型。一般我们使用内部联结,但使用外部联结也是有效的
- 保证使用正确的联结条件,否则将返回不正确的数据
- 应该总是提供联结条件,否则会得出笛卡儿积
- 在一个联结中可以包含多个表,甚至对每个联结可以采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们前,分别测试每个联结。这将使故障排除更为简单。