第12章 联结表
联结
关系数据库:把信息分解成多个表,一类数据一个表,各表通过某些共同的值相互关联
可伸缩(scale):能够适应不断增加的工作量而不失败。
引用完整性表示DBMS强制实施数据完整性规则。
创建联结
SELECT vend_name, prod_name, prod_price
FROM Vendors,Products
WHERE Vendors.vend_id=Products.vend_id;
没有WHERE会返回笛卡儿积的联结,也称叉联结
内联结 = 等值联结
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
联结多个表:
#显示订单20007的物品
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=20007;
第11章中子查询使用联结的相同查询:
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='RGAN01';
第13章 创建高级联结
使用表别名
SELECT RTRIM(vend_name)+'('+RTRIM(vend_country)+')'
AS vend_title
FROM Vendors
ORDER BY vend_name;
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='RGAN01';
Oracle没有AS,使用Customers C
表别名只在查询执行中使用,与列表名不一样,表别名不返回到客户端。
使用不同类型的联结
- 自联结
#找出Jim Jones工作的公司,然后找出在该公司工作的顾客
SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name=(SELECT cust_name
FROM Customers
WHERE cust_contact='Jim Jones');
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name=c2.cust_name
AND c2.cust_contact='Jim Jones';
- 自然联结
自然联结排除多次出现相同的列,使每一列只返回一次。
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='RGAN01';
- 外联结
内联结,检索所有顾客及其订单:
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 JOIN Orders
ON Customers.cust_id=Orders.cust_id;
两种基本的外联结形式:左外联结和右外联结
全外联结:FULL OUTER JOIN,包含两个表的不关联的行,MySQL不支持。
使用带聚集函数的联结
#检索所有顾客及每个顾客所下的订单数
SELECT 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_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;
使用联结和联结条件
- 一般使用内联结,但使用外联结也有效
- 确切语法看相应的DBMS
- 保证使用正确的联结条件
- 应总是提供条件,否则会得出笛卡儿积
- 在一个联结中可以包含多个表
第14课 组合查询
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN('IL', 'IN', 'MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name='Fun4All';
UNION必须由两条或两条以上的SELECT语句组成
UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)
列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含转换的类型
- 包含重复的行:UNION ALL
取消重复的行:UNION
3.对组合查询结果排序
在用UNION组合查询时,只能使用一条ORDER BY子句,必须位于最后一条SELECT语句之后,DBMS将用它排序所有SELECT语句返回的所有结果。
网友评论