笔记参考SQL必知必会,把书中一些有用的资源摘录下来,方便以后查阅,也供道友们参考
SQL最强大的功能之一就是能在数据查询的执行中联结(join)表。联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分。
联结表我的理解是如果我们需要输出多个表的查询数据,我们就需要使用联结表,比如我们输出2个表的中的一个属性时,我们就需要从2个表中查询,之前有类似的子查询,当查询的两者有关系时,可以使用子查询来查询,但当两者没关系时,那我们只能用联结表查询,可能理解的有点片面,之后经过时间积累在修改。希望道友能指正。。。。
SQL最强大的功能之一就是能在数据查询的执行中联结(join)表。联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分。
2 、创建联结
SELECT vend_name, prod_name, prod_price FROM Vendors, Products WHERE Vendors.vend_id = Products.vend_id;
vend_name prod_name prod_price
-------------------- -------------------- ---------
Doll House Inc. Fish bean bag toy 3.4900
Doll House Inc. Bird bean bag toy 3.4900
Doll House Inc. Rabbit bean bag toy 3.4900
Bears R Us 8 inch teddy bear 5.9900
看FROM子句。与以前的SELECT语句不一样,这条语句的FROM子句列出了两个表:Vendors和Products。它们就是这条SELECT语句联结的两个表的名字。这两个表用WHERE子句正确地联结,WHERE子句指示DBMS将Vendors表中的vend_id与Products表中的vend_id匹配起来。
2.3、内联结
上面的联结是等值联结,它基于两个表之间的相等测试。这种联结也称为内联结(inner join)。其实,可以对这种联结 使用稍微不同的语法,明确指定联结的类型。下面的SELECT语句返回与前面例子完全相同的。
SELECT vend_name, prod_name, prod_price FROM Vendors INNER JOIN Products ON Vendors.vend_id = Products.vend_id;
中的SELECT与前面的SELECT语句相同,但FROM子句不同。这里,两个表之间的关系是以INNER JOIN指定的部分FROM子句。在使用 这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递给ON的实际条件与传递给WHERE的相同。
根据DBMS支持选择这两种方法
2.4、联结多个表
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;
性能考虑: DBMS在运行时关联指定的每个表,以处理联结。这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表。联结的表越多,性能 下降越厉害。
3、创建高级联结
介绍如何使用表别名,如何对被联结的表使用聚集函数
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’;
FROM子句中的三个表全都有别名。Customers AS C使用C作为Customers的别名,如此等等。这样,就可以使用省略的C而不用全 名Customers。在这个例子中,表别名只用于WHERE子句。其实它不仅能用于WHERE子句,还可以用于SELECT的列表、ORDER BY子句以及其他语句部分。
需要注意,表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户端。
3.2、使用不同类型的联结
迄今为止,我们使用的只是内联结或等值联结的简单联结。现在来看三种其他联结:自联结(self-join)、自然联结(natural join)和外联结 (outer join)。
3.2.1、自联结
假如要给与Jim Jones同一公司的所有顾客发送一封信件。这个查询要求首先找出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语句做了一个简单检索,返回Jim Jones工作公司的cust_name。该名字用于外部查询的WHERE子句中,以检索出为该公司工作的所有雇员
3.2.3、外联结
http://blog.sina.com.cn/s/blog_3d48dbb70100hyz4.html非常好的博客讲解了外联结
3.2.4、使用带聚集函数的联结
要检索所有顾客及每个顾客所下的订单数,下面的代码使用COUNT()函数完成此工作:
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语句使用INNER JOIN将Customers和Orders表互相关联。GROUP BY子句按顾客分组数据,因此,函数调 用COUNT(Orders.order_num)对每个顾客的订单计数,将它作为num_ord返回。
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;
这个例子使用左外部联结来包含所有顾客,甚至包含那些没有任何订单的顾客。结果中也包含了顾客1000000002,他有0个订单。
使用联结和联结条件
注意所使用的联结类型。一般我们使用内联结,但使用外联结也有效。 关于确切的联结语法,应该查看具体的文档,看相应的DBMS支持何种语法。 保证使用正确的联结条件(不管采用哪种语法),否则会返回不正确的数据。 应该总是提供联结条件,否则会得出笛卡儿积。 在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们前分别测试每个联结。这会使故障排除更为简单。