2009-11-22 4 views
5

Я думал о синтаксисе внутренних соединений в реализации SQL в Oracle, и вот то, что кажется немного противоречивое:внутренние соединения в оракула

Допустим, у вас есть два отношения кредита (loan_number, branch_name, количество) и заемщика (customer_name, loan_number). loan_number - это атрибут, общий для обеих таблиц. Теперь 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 ожидает, что ON ... часть статьи

Учитывая, что внутреннее соединение - это просто крест-соединение с условием фильтрации, вы, ребята, думаете, что это несогласованность в реализации SQL Oracle? Я что-то упускаю? Мне было бы интересно услышать другие мнения. Благодарю.

Как Давид отметил в своем ответе синтаксис:

select * 
from loan cross join borrower; 

Несмотря на то, что я не знал, что предыдущий вариант синтаксиса я все еще думаю, что это непоследовательно. Наличие ключевого слова cross join в дополнение к разрешению внутреннего соединения без условия соединения будет прекрасным. Перекрестное объединение на самом деле является внутренним соединением без условия соединения, почему бы не выразить его как внутреннее соединение без условия соединения?

+3

(a) Так как это стандарт SQL, определенный им, и (b), поскольку CROSS JOIN не содержит информации, которая не была в двух отдельных таблицах, обычно (но не всегда) расточительна и требует специального синтаксиса для вызова ресурсов «впустую». –

+1

Что сказал Джонатан Леффлер, стандарт SQL явно определяет кросс-соединение. Вы делали предположение, что перекрестное присоединение является особой формой внутреннего соединения. –

+0

@jhartelt крестовое соединение и внутреннее соединение являются и декартовыми продуктами, но внутреннее объединение фильтрует результаты. – neesh

ответ

4

Я согласен с тем, что это непротиворечиво.

Но я бы утверждать, что реализация Oracle хорошая вещь:

  • когда вы делаете присоединиться, вы почти всегда хотите включить условие фильтрации, поэтому ON часть является обязательным.
  • Если вы действительно не хотите иметь условие фильтра (вы действительно уверены?), Вы должны сказать Oracle явно с помощью sytax CROSS JOIN.

Имеет большой смысл для меня не быть на 100% последовательным - это помогает избежать ошибок.

+0

Я согласен с тобой. кросс-соединения, вероятно, не то, что пользователь имел в виду, поэтому они явно указывают на то, что они хотят. – neesh

3

SELECT * 
FROM Loan 
CROSS JOIN Borrower 

Нет несоответствий.

2

Этот способ выражения внутренних соединений:

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

не рекомендуется в течение почти 20 лет. Это было сохранено, потому что это просто действительное выражение, которое, случается, передает внутреннее соединение. Я хотел бы сосредоточиться на использовании версии ближе к текущему стандарту, минимизируя шансы на непонимание и ошибки.

+1

Oracle поддерживает только синтаксис соединения ANSI 92 с версии 9i. Это было выпущено в 2001 году, что значительно меньше «почти двадцати лет». Кроме того, вопрос задавал вопрос о явных несоответствиях в реализации Oracle стандарта ANSI. – APC

3

Oracle также поддерживает синтаксис естественного соединения, который объединяет две таблицы на основе общих имен столбцов. Это будет работать в вашем случае, потому что обе таблицы имеют столбец LOAN_NUMBER.

SELECT * 
FROM Loan 
NATURAL JOIN Borrower 

Теперь, в этом случае можно сделать то же самое, что использование ключевого слова natural строго необходимо. Но если следовать логике, мы в конечном итоге с ситуацией, в которой это утверждение может быть либо перекрестное соединение или естественное соединение, в зависимости от имен столбцов:

SELECT * 
FROM Loan 
JOIN Borrower 

Это явно нежелательно, если только из-за переименование КРЕДИТА .LOAN_NUMBER в LOAN_ID изменит набор результатов.

Итак, есть ваш ответ: неоднозначность.

+0

Ваш ответ имеет большой смысл. Однако, если бы эстетика была в моих силах, я бы разрешил крест-соединение быть определенным как выбрать * из заемщика займа и использовать ключевое слово natural, чтобы указать естественное соединение. – neesh