testbook

Extension of JOIN

  • 重复连接
    有时候同一张表在一次查询中需要和多张其他表连接。假设我们有三张表table1, table2和table3。其中table1要和table2和table3各连接一次。这种情况下,用户需要给table1在两次连接中起两个不同的化名来让Inceptor能够分辨在各子句中table1的角色:
  • SELECT t1.col1, tb1.col2, t2.col1, t3.col,...
    FROM table1 t1 INNER JOIN table2 t2
        ON t1.col1 = t2.col1
        INNER JOIN table3 t3
        ON t2.col2 = t3.col1
        INNER JOIN table1 tb1
        ON t3.col = tb1.col2;
    

  • SELF JOIN
    一张表也可以和自己连接,此时也需要给表取两个不同的化名来让Inceptor能够分辨在各子句中表的角色。我们用一个包含了雇员信息的表来作为例子。表中含有雇员姓、名、工号、上级工号和入职日期。
  • SELECT * FROM employee_table;
    10817            Li            Xintao             94832            20140509
    13049            Zhang         Mingzhe            94832            20140616
    58290            Wang          Weilun             12083            20120901
    94832            Zhou          Liren              12083            20111212
    12083            Zheng         Xi                 56412            20110916
    56412            Wu            Siyi               NULL             20110916
    
    现在我们用SELF JOIN来查询所有雇员和他们的上级的姓名:
    例子

    SELECT e.lname, e.fname, sup.lname, sup.fname
    FROM empolyee_table e INNER JOIN employee_table sup
        ON e.sup_id = sup.id;
    Li        Xintao        Zhou      Liren
    Zhang     Mingzhe       Zhou      Liren
    Wang      Weilun        Zheng     Xi
    Zhou      Liren         Zheng     Xi
    Zheng     Xi            Wu        Siyi
    
    注意,因为WuSiyi没有上级,他的记录没有在这张表中出现。要显示他的信息,可以使用SELF OUTER JOIN:

  • SELF OUTER JOIN
  • SELECT e.lname, e.fname, sup.lname, sup.fname
    FROM empolyee_table e LEFT OUTER JOIN employee_table sup
        ON e.sup_id = sup.id;
    Wu        Siyi          NULL      NULL
    Li        Xintao        Zhou      Liren
    Zhang     Mingzhe       Zhou      Liren
    Wang      Weilun        Zheng     Xi
    Zhou      Liren         Zheng     Xi
    Zheng     Xi            Wu        Siyi
    
    这里我们用了左外连接。表也可以和自己右外连接和全外连接。

  • NON-EQUI JOIN
    到现在为止,我们只用到了等价连接(equi-join),也就是join条件是一个等式。我们也可以将表不等价连接(non-equi join)。我们用一个自不等价连接作为例子。假设公司想要在员工中间组织一次下棋比赛,每对员工之间都要进行一场比赛,我们想要生成包含所有员工对的数据:
  • SELECT e1.lname, e1.fname, e2.lname, e2.fname
    FROM employee_table e1 INNER JOIN employee_table e2
        ON e1.id != e2.id;
    
    这里join条件是e1.id != e2.id,因为一个人不能和自己比赛。这条指令会导致每个员工对都会重复一次,所以我们可以修改join条件为e1.id < e2.id 。 如果两张表中有两对同名列,而且 有矛盾(where table1.col1=table2.col1, table1.col2\neq table2.col2)?