SQL自联结

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处理联结远比处理子查询快得多。应该试一下两种方法,以确定哪一种的性能更好。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!

 

SQL教程