代码之家  ›  专栏  ›  技术社区  ›  neesh

Oracle中的内部联接

  •  5
  • neesh  · 技术社区  · 15 年前

    我在考虑Oracle的SQL实现中内部联接的语法,这里有一些似乎有点不一致的地方:

    假设您有两个关系贷款(贷款编号、分行名称、金额)和借款人(客户名称、贷款编号)。贷款编号是两个表的共同属性。现在,Oracle为您提供了两种表示内部联接的方法:

    select * 
    from loan, borrower 
    where loan.loan_number = borrower.loan_number;
    

    上述声明等同于:

    select * 
    from loan 
         inner join borrower 
         on loan.loan_number = borrower.loan_number;
    

    但是,在表示交叉联接时,只有一种方法可以表示它:

    select * 
    from loan, borrower;
    

    以下语句语法错误:

    select * 
    from loan 
         inner join borrower; 
    

    这是无效的;Oracle要求打开…条款的一部分

    考虑到内部联接只是一个带有过滤条件的交叉联接,你们认为这在Oracle的SQL实现中是不一致的吗?我错过什么了吗? 我想听听其他意见。谢谢。

    正如大卫在回答中指出的那样,句法是:

    select * 
    from loan cross join borrower;
    

    尽管我不知道上面的语法,但我仍然认为它是不一致的。除了允许没有联接条件的内部联接之外,还可以使用cross-join关键字。交叉联接实际上是没有联接条件的内部联接,为什么不将其表示为没有联接条件的内部联接?

    4 回复  |  直到 15 年前
        1
  •  4
  •   Thorsten    15 年前

    我同意这是不一致的。

    但我认为Oracle实现是一件好事:

    • 当您执行联接时,您几乎总是希望包含一个筛选条件,因此 ON 零件是强制性的。
    • 如果你真的,真的不想有一个过滤条件(你真的确定吗?),你必须明确地告诉Oracle CROSS JOIN 西贡

    对我来说,保持100%的一致性是很有意义的——这有助于避免你的错误。

        2
  •  3
  •   David    15 年前
    
    SELECT *
    FROM Loan
    CROSS JOIN Borrower
    

    没有不一致。

        3
  •  3
  •   APC    15 年前

    Oracle还支持自然联接语法,它根据共享列名称联接两个表。这在您的情况下是可行的,因为两个表都有一个名为Loan_Number的列。

    SELECT *
    FROM Loan
    NATURAL JOIN Borrower
    

    现在,在这种情况下也可以提出同样的论点,即使用关键字natural是完全不必要的。但是,如果我们遵循逻辑,最终会遇到这样一种情况:根据列名的不同,此语句可以是交叉联接,也可以是自然联接:

    SELECT *
    FROM Loan
    JOIN Borrower
    

    这显然是不可取的,如果只是因为将loan.loan\u编号重命名为loan\u id会更改结果集。

    所以,你的答案是:消除歧义。

        4
  •  2
  •   Otávio Décio    15 年前

    这种表达内部连接的方式:

    select * from loan, borrower where loan.loan_number = borrower.loan_number;
    

    近20年不推荐使用。之所以保留它,是因为它只是一个恰好传递内部联接的有效表达式。我会集中精力使用更接近当前标准的版本,尽量减少误解和消除错误的可能性。