SQL总结(五)

联结表

关系型数据库

相同的数据出现多次不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表,各表通过某些相同的值互相关联。
比如,产品表E中有1~10产品,其中五个产品是公司A的,那么我们最好不要在E中加上A公司的其他信息 (只存储公司的ID),比如地址、电话等,而是应该新建一个公司表F,里面包含公司的信息。
这样做的好处是,表A中不会有公司的重复信息(除了ID),不会浪费时间空间;在对公司信息进行修改时,只需要修改F表的信息即可。

联结的使用

联结是一种机制,用来在一条SELECT语句中关联表,使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。联结在实际的数据库中不存在。
例子:
SELECT vend_name,prod_name,prod_price FROM Vendors,Products WHERE Vendors.vend_id=Products.vend_id;

WHERE子句的重要性

WHERE子句作为过滤条件,只包含那些匹配给定条件(联结条件)的行,如果两个表没有联结条件(WHERE Vendors,Products;),那么将以这种形式输出(即:A表的每一行匹配B表的每一行,总数为m*n)。
要保证所有联结都有WHERE子句。
另一种联结格式
SELECT vend_name,prod_name,prod_price FROM Vendors INNER JOIN Products ON Vendors.vend_id=Products.vend_id;这是一种标准写法,之前是一种简单写法。

联结多个表

用多个WHERE可以联结多个表
SELECT vend_name,prod_name,prod_price,quantity FROM OrderItems,Vendors,Products WHERE Vendors.vend_id=Products.vend_id AND OrderItems.prod_id=Products.prod_id AND order_num=20007;

创建高级联结

使用表别名

作用:1、缩短SQL语句;2、能在一条SELECT语句中多次使用相同的表。
例子:
SELECT vend_name,prod_name,prod_price FROM Vendors AS V,Products AS P WHERE V.vend_id=P.vend_id;
注意,表别名只在查询执行时使用,与列别名不同,它不返回到客户端。

使用不同类型的联结

自联结、自然联结、外联结
自联结
例子:查找与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_name='Jim Jones';
自然联结
标准的联结返回所有数据,相同的列甚至多次出现,自然联结排除多次出现,使每一列只返回一次。它要求你只选择那些唯一的列,一般通过对一个表使用通配符(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='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 OUTER JOIN Orders ON Customers.cust_id=Orders.cust_id;
以上,使用LEFT OUTER JOIN从FROM子句左边的表Customers中选择所有的行,如果是RIGHT OUTER JOIN的话,那对应的就是Orders中的所有行。
另外还有一种全外联结FULL OUTER JOIN,但是多数DBMS不支持。

使用带聚集函数的联结

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;检索所有顾客及每个顾客下的订单数。

posted @ 2018-05-23 13:35  歪胡子的日常  阅读(187)  评论(0编辑  收藏  举报