SQL自联结,如前所述,使用表别名的一个主要原因是能在一条SELECT语句中不止一次引用相同的表。下面举一个例子。
假如要给与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');
输出结果如下:
cust_id cust_name cust_contact
-------- -------------- --------------
1000000003 Fun4All Jim Jones
1000000004 Fun4All Denise L. Stephens
这是第一种解决方案,使用了子查询。内部的SELECT语句做了一个简单检索,返回Jim Jones工作公司的cust_name。该名字用于外部查询的WHERE子句中,以检索出为该公司工作的所有雇员(参考子查询)。
现在来看使用联结的相同查询:
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';
输出结果如下:
cust_id cust_name cust_contact
------- ----------- --------------
1000000003 Fun4All Jim Jones
1000000004 Fun4All Denise L. Stephens
提示:Oracle中没有AS
Oracle用户应该记住去掉AS。
此查询中需要的两个表实际上是相同的表,因此Customers表在FROM子句中出现了两次。虽然这是完全合法的,但对Customers的引用具有歧义性,因为DBMS不知道你引用的是哪个Customers表。
解决此问题,需要使用表别名。Customers第一次出现用了别名c1,第二次出现用了别名c2。现在可以将这些别名用作表名。例如,SELECT语句使用c1前缀明确给出所需列的全名。如果不这样,DBMS将返回错误,因为名为cust_id、cust_name、cust_contact的列各有两个。DBMS不知道想要的是哪一列(即使它们其实是同一列)。WHERE首先联结两个表,然后按第二个表中的cust_contact过滤数据,返回所需的数据。
提示:用自联结而不用子查询
自联结通常作为外部语句,用来替代从相同表中检索数据的使用子查询语句。虽然最终的结果是相同的,但许多DBMS处理联结远比处理子查询快得多。应该试一下两种方法,以确定哪一种的性能更好。
酷客网相关文章:
评论前必须登录!
注册