2017-01-11 5 views
3

Ich lerne Oracle SQL und jetzt bin ich auf Joins Kapitel fest. Ich kann nicht verstehen den Unterschied zwischen Join und Natur JoinWas ist der Unterschied zwischen Join und 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 Taylor 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 

Ich weiß nicht, warum Ich erhalte unterschiedliche Ergebnisse, wenn sowohl Join als auch Natural Join eine ähnliche Funktion haben.

+2

IMO, 'Natur Join' Verwendung ** implizite ** Join-Spalten, die alle Spalten mit demselben Namen in zwei Tabellen überprüfen und verbinden. Mit 'Join' müssen Sie ** explizite ** Join-Spalten in' ON'-Anweisungen deklarieren (vielleicht den gleichen Namen, vielleicht nicht, vielleicht hat 2 Tabellen 10 gleiche Spaltennamen, sondern nur 2 verschiedene Spaltennamen, ....). –

+2

Ein gutes Beispiel dafür, warum Sie niemals natürliche Joins verwenden sollten. In Ihrem Fall verwendet der natürliche Join mehr Spalten, um ihn zu verknüpfen, was ihn restriktiver macht. Welche Spalten sind das? Ich weiß es nicht, weil es nicht gezeigt wird! –

+0

Ein gutes Beispiel, bei dem ein kurzes Attribut, dessen Präfix lediglich durch seinen Tabellennamen impliziert wird, Probleme verursacht, wenn es in relationalen Operatoren verwendet wird, die andere Tabellen, z. 'end_date' in' employees', wo das explizite 'employment_end_date' besser wäre. – onedaywhen

Antwort

10

Verwenden Sie nicht natural join. Es ist ein Fehler, der darauf wartet, zu passieren.

Eine explizite join hat eine on Klausel, die die Bedingungen für den Abgleich zwischen den Tabellen auflistet. In Ihrem Beispiel ist department_id für diesen Zweck (obwohl andere Spalten möglicherweise verfügbar sind).

Die using Klausel ist eine weitere sehr nützliche Alternative. Sie verwenden es als:

FROM employees e JOIN 
    job_history j 
    USING (department_id) 

Es findet department_id in beiden Tabellen und verwendet diese für die Join-Bedingung.

NATURAL JOIN fügt eine JOIN Bedingungen für alle Spalten in den Tabellen, die gleich sind. In Ihrem Fall wäre dies department_idplus andere Spalten. Das Problem - wie Sie feststellen - ist, dass Sie nicht wissen, welche Spalten für die join verwendet werden. Noch schlimmer, Explizite Fremdschlüssel Referenzen werden nicht verwendet.

Da Ihre Abfrage nicht angibt, was passiert, gibt es viel Spielraum für Fehler und Fehler. Es gibt keinen tatsächlichen Bedarf für NATURAL JOIN, also können Sie auch nur lernen, ON und USING zu verwenden.

+1

Die einzige Situation (und ich denke, dass es nützlich ist), wenn ich 'NATURAL JOIN' verwende, ist im Falle von geschachtelten Tabellen, z. 'SELECT * FROM MY_TABLE NATÜRLICHE JOIN TABLE (NESTED_TABLE_COLUMN)' –

+0

Vielen Dank für Ihre Hilfe !!! – Rattlesnake

2

Nur um zu verdeutlichen, was offensichtlich sein sollte: Ihre erste Abfrage ergibt ein anderes Ergebnis, weil es Ihrer zweiten Abfrage nicht semantisch entspricht.

Hier ist ein Vorschlag rewite der NATURAL JOIN Version:

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; 

Es gibt keine ‚Warte Fehler passieren‘ in der obigen Abfrage, obwohl ich - Schock! Grusel! - verwendet SELECT * zusätzlich zu NATURAL JOIN (beide vom SQL-Flock kontraindiziert): das Projizieren von Spalten in den CTEs schützt Ihre Abfrage vor dem Szenario, in dem Spalten den Tabellen employees und job_history hinzugefügt werden.

+0

Danke für Ihre Hilfe. Ich habe diesen Beitrag erstellt, weil ich neu in Oracle-Programmierung bin, aber in diesen Tagen habe ich ein wenig mehr über SQL-Joins gelesen. Jetzt übe ich PLSQL und ich bin mehr über Oracle SQL bekannt. Danke noch einmal!!! – Rattlesnake

Verwandte Themen