2017-01-11 2 views
3

Я изучаю Oracle SQL, и теперь я застрял в главе Joins. Я не могу понять разницу между Присоединяйтесь и Natural JoinВ чем разница между Join и Natural Join?

SELECT   employee_id, job_id, department_id, 
       e.last_name, e.hire_date, j.end_date 
FROM   employees e 
NATURAL JOIN job_history j; 

176 SA_REP 80 Тейлор 24/03/2006 31/12/2006

SELECT   e.employee_id, e.job_id, e.department_id, 
       e.last_name, e.hire_date, j.end_date 
FROM   employees e 
JOIN   job_history j 
ON    (e.department_id = j.department_id) 
ORDER BY  employee_id, last_name; 

172 SA_REP 80 Bates 24/03/2007 31/12/2006 
173 SA_REP 80 Kumar 21/04/2008 31/12/2007 
173 SA_REP 80 Kumar 21/04/2008 31/12/2006 
174 SA_REP 80 Abel 11/05/2004 31/12/2007 
174 SA_REP 80 Abel 11/05/2004 31/12/2006 
175 SA_REP 80 Hutton 19/03/2005 31/12/2007 
175 SA_REP 80 Hutton 19/03/2005 31/12/2006 
176 SA_REP 80 Taylor 24/03/2006 31/12/2007 
176 SA_REP 80 Taylor 24/03/2006 31/12/2006 
177 SA_REP 80 Livingston 23/04/2006 31/12/2007 
177 SA_REP 80 Livingston 23/04/2006 31/12/2006 

Я не знаю, почему Я получаю разные результаты, если как Join, так и Natural Join имеют схожие функции.

+2

IMO, 'Nature Join' use ** implicit ** join columns, которые проверяют и объединяют все столбцы с одинаковым именем в двух таблицах. С 'Join' вы должны ** явно ** объявлять столбцы объединения в операциях' ON' (может быть, одно и то же имя, возможно, нет, возможно, 2 таблицы имеют 10 одинаковых имен столбцов, а просто присоединяются к 2 различным именам столбцов, ....). –

+2

Хороший пример того, почему вы никогда не должны использовать естественные соединения. В вашем случае естественное соединение использует больше столбцов для объединения, что делает его более ограничительным. Какие столбцы это? Я не знаю, как это не показано! –

+0

Хороший пример, где короткий атрибут, префикс которого просто подразумевается его именем таблицы, вызывает проблемы при использовании в реляционных операторах, связанных с другими таблицами, например. 'end_date' в' employees', где явное 'job_end_date' будет лучше. – onedaywhen

ответ

10

Не использовать natural join. Это ошибка, ожидающая своего появления.

В явном виде join содержится условие on, в котором перечислены условия для сопоставления между таблицами. В вашем примере для этой цели используется department_id (хотя могут быть доступны и другие столбцы).

Статья using - еще одна очень полезная альтернатива. Вы можете использовать его как:

FROM employees e JOIN 
    job_history j 
    USING (department_id) 

department_id Он находит в обеих таблицах и использует для условия объединения.

NATURAL JOIN добавляет JOIN условия для всех столбцов в таблицах, которые являются одинаковыми. В вашем случае это будет department_idплюс другие столбцы.

Проблема - как вы переживаете - это то, что вы не знаете, какие столбцы используются для join. Хуже того, явным образом ссылки внешнего ключа не используются.

Поскольку в вашем запросе не указано, что происходит, существует множество возможностей для ошибок и ошибок. Нет необходимости в NATURAL JOIN, поэтому вы можете просто научиться использовать ON и USING.

+1

Единственная ситуация (и я думаю, что это полезно), когда я использую 'NATURAL JOIN' в случае вложенных таблиц, например. 'SELECT * FROM MY_TABLE NATURAL JOIN TABLE (NESTED_TABLE_COLUMN)' –

+0

Спасибо за вашу помощь !!! – Rattlesnake

2

Просто, чтобы четко указать, что должно быть очевидно: ваш первый запрос дает другой результат, потому что он не является семантически эквивалентным второму запросу.

Вот предложили rewite версии NATURAL JOIN:

WITH e AS 
    (SELECT employee_id, job_id, department_id, 
       last_name, hire_date 
     FROM employees), 
    j AS 
    (SELECT department_id, end_date 
     FROM job_history) 
SELECT * 
    FROM e NATURAL JOIN j 
ORDER 
    BY employee_id, last_name; 

Там нет «ошибки замедленного действия» в приведенном выше запросе, даже если у меня есть - шок! ужастик! - используется SELECT * в дополнение к NATURAL JOIN (оба противопоказаны стекой SQL): проецирующие столбцы в CTE защищают ваш запрос от сценария, в котором столбцы добавляются в таблицы employees и job_history.

+0

Спасибо за помощь. Я создал этот пост, потому что я новичок в программировании Oracle, но в эти дни я читал немного больше о соединениях SQL. Теперь я занимаюсь PLSQL, и я больше знаком с Oracle SQL. Еще раз спасибо!!! – Rattlesnake

Смежные вопросы