Joins – Mehrere Tabellen verknüpfen

Fach: Informationstechnologie – Datenbanksysteme
Schulstufe: 11. Schulstufe – HTL Informatik
Voraussetzungen: DQL – SELECT, WHERE, GROUP BY, SCOTT-Schema
Autor: HTL Pinkafeld – IF/IT



1. Warum Joins?

1.1 Daten sind auf mehrere Tabellen verteilt

Durch Normalisierung werden Daten auf mehrere Tabellen aufgeteilt, um Redundanz zu vermeiden. Für aussagekräftige Abfragen müssen diese Tabellen wieder zusammengeführt werden:

-- EMP zeigt nur DEPTNO = 10, 20, 30
SELECT ENAME, DEPTNO FROM EMP WHERE EMPNO = 7839;
-- KING   10

-- DEPT erklärt was Abteilung 10 bedeutet
SELECT DNAME, LOC FROM DEPT WHERE DEPTNO = 10;
-- ACCOUNTING   NEW YORK

-- Mit JOIN: beide Informationen in einer Abfrage
SELECT ENAME, DNAME, LOC
FROM   EMP JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO
WHERE  EMPNO = 7839;
-- KING   ACCOUNTING   NEW YORK

1.2 Join-Typen im Überblick

Tabelle A          Tabelle B

  1                   1
  22    INNER JOIN  → nur gemeinsame Zeilen
  3                   3
  4                        nur in A
             5             nur in B

LEFT  OUTER JOIN  → alle aus A + passende aus B
RIGHT OUTER JOIN  → passende aus A + alle aus B
FULL  OUTER JOIN  → alle aus A + alle aus B
CROSS JOIN        → jede Zeile aus A × jede Zeile aus B
SELF  JOIN        → Tabelle mit sich selbst verknüpft

1.3 Die Join-Bedingung

Ein Join benötigt immer eine Join-Bedingung – sie legt fest, welche Zeilen aus Tabelle A zu welchen Zeilen aus Tabelle B gehören:

-- Join-Bedingung: EMP.DEPTNO muss gleich DEPT.DEPTNO sein
FROM EMP JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO
                   ─────────────────────────────
                        Join-Bedingung

2. Kartesisches Produkt – CROSS JOIN

2.1 Was ist ein kartesisches Produkt?

Ohne Join-Bedingung wird jede Zeile der ersten Tabelle mit jeder Zeile der zweiten Tabelle kombiniert:

-- 14 Mitarbeiter × 4 Abteilungen = 56 Zeilen!
SELECT ENAME, DNAME
FROM   EMP CROSS JOIN DEPT;

-- Ältere Oracle-Syntax (ohne JOIN-Schlüsselwort, kein WHERE):
SELECT ENAME, DNAME
FROM   EMP, DEPT;

2.2 Wann sinnvoll?

Das kartesische Produkt ist fast immer ein Fehler – es entsteht meist durch eine vergessene Join-Bedingung. Gelegentlich wird es absichtlich eingesetzt, z.B. um Kalender oder Kombinationstabellen zu erzeugen.

Merke: Bei n Zeilen in Tabelle A und m Zeilen in Tabelle B entstehen n × m Zeilen. Bei großen Tabellen kann das den Server zum Stillstand bringen!


3. INNER JOIN – Schnittmenge

3.1 Grundprinzip

Der INNER JOIN gibt nur jene Zeilen zurück, für die in beiden Tabellen eine passende Zeile gemäß der Join-Bedingung existiert:

EMP (14 Zeilen)          DEPT (4 Zeilen)
DEPTNO: 10,20,30,...     DEPTNO: 10,20,30,40

INNER JOIN:
→ Nur Zeilen wo EMP.DEPTNO in DEPT vorkommt
→ Abteilung 40 (OPERATIONS) hat keine Mitarbeiter → wird nicht ausgegeben
→ Alle 14 EMP-Zeilen haben einen passenden DEPT-Eintrag → alle 14 bleiben

3.2 ANSI-Syntax (empfohlen)

-- Grundlegende Syntax
SELECT e.ENAME, e.JOB, e.SAL, d.DNAME, d.LOC
FROM   EMP e
       INNER JOIN DEPT d ON e.DEPTNO = d.DEPTNO;

-- INNER ist optional – JOIN allein bedeutet immer INNER JOIN
SELECT e.ENAME, e.JOB, e.SAL, d.DNAME, d.LOC
FROM   EMP e
       JOIN DEPT d ON e.DEPTNO = d.DEPTNO;

Ergebnis (14 Zeilen):

ENAME   JOB        SAL   DNAME       LOC
------  ---------  ----  ----------  --------
SMITH   CLERK       800  RESEARCH    DALLAS
ALLEN   SALESMAN   1600  SALES       CHICAGO
WARD    SALESMAN   1250  SALES       CHICAGO
...
KING    PRESIDENT  5000  ACCOUNTING  NEW YORK

3.3 Mit WHERE kombinieren

-- Nur Mitarbeiter aus DALLAS mit Gehalt > 1500
SELECT e.ENAME, e.SAL, d.LOC
FROM   EMP e
       JOIN DEPT d ON e.DEPTNO = d.DEPTNO
WHERE  d.LOC = 'DALLAS'
  AND  e.SAL > 1500;

-- Nur Manager und ihr Standort
SELECT e.ENAME, e.JOB, d.DNAME, d.LOC
FROM   EMP e
       JOIN DEPT d ON e.DEPTNO = d.DEPTNO
WHERE  e.JOB = 'MANAGER'
ORDER BY d.DNAME;

3.4 NATURAL JOIN und USING

Oracle kennt zwei Kurzformen für den INNER JOIN:

-- NATURAL JOIN: verknüpft automatisch alle gleichnamigen Spalten
-- (Vorsicht: verknüpft ALLE gemeinsamen Spalten – kann unbeabsichtigt sein!)
SELECT ENAME, DNAME
FROM   EMP NATURAL JOIN DEPT;

-- USING: explizit eine gemeinsame Spalte angeben
SELECT ENAME, DNAME, LOC
FROM   EMP JOIN DEPT USING (DEPTNO);
-- Vorteil: DEPTNO darf in SELECT nicht qualifiziert werden (kein e.DEPTNO)

Empfehlung für den Unterricht: Immer die ON-Syntax verwenden – sie ist am klarsten und flexibelsten.


4. Tabellenaliase und Spaltenqualifizierung

4.1 Wozu Tabellenaliase?

Bei Joins müssen Spalten, die in mehreren Tabellen existieren, qualifiziert werden – sonst weiß Oracle nicht, welche Tabelle gemeint ist:

-- FEHLER: DEPTNO ist in EMP und DEPT – welches ist gemeint?
SELECT ENAME, DEPTNO, DNAME
FROM   EMP JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;
-- ORA-00918: column ambiguously defined

-- RICHTIG: Spalte qualifizieren
SELECT e.ENAME, e.DEPTNO, d.DNAME
FROM   EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO;

4.2 Regeln für Tabellenaliase

-- Alias direkt nach dem Tabellennamen (kein AS!)
FROM EMP e            -- Kurzform (empfohlen)
FROM EMP AS e         -- Mit AS (funktioniert in Oracle auch)

-- Sobald ein Alias vergeben ist, MUSS er verwendet werden
-- (Tabellenname ohne Alias ist dann nicht mehr gültig)
SELECT EMP.ENAME ...  -- FEHLER wenn Alias 'e' vergeben
SELECT e.ENAME ...    -- RICHTIG

4.3 Spaltennamen eindeutig machen

-- Wenn Spaltenname in nur einer Tabelle vorkommt: Qualifizierung optional
SELECT e.ENAME,         -- nur in EMP → e. optional, aber guter Stil
       e.SAL,           -- nur in EMP
       e.DEPTNO,        -- in EMP und DEPT → muss qualifiziert werden
       d.DNAME,         -- nur in DEPT
       d.LOC            -- nur in DEPT
FROM   EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO;

5. JOIN über mehrere Tabellen

5.1 Drei Tabellen verknüpfen

-- EMP + DEPT + SALGRADE: Mitarbeiter mit Abteilung und Gehaltsklasse
SELECT e.ENAME,
       e.SAL,
       d.DNAME,
       d.LOC,
       s.GRADE         AS gehaltsklasse
FROM   EMP     e
       JOIN DEPT     d ON e.DEPTNO = d.DEPTNO
       JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL
ORDER BY s.GRADE, e.SAL;

SALGRADE verwendet einen Bereichs-Join (BETWEEN), da kein gemeinsamer Schlüssel existiert – mehr dazu in Kapitel 10 (NON-EQUIJOIN).

5.2 Reihenfolge der Joins

Oracle führt Joins von links nach rechts aus, aber der Optimizer kann die Reihenfolge selbst wählen. Für die Lesbarkeit gilt:

-- Empfehlung: Haupttabelle zuerst, dann abhängige Tabellen
FROM  EMP e
      JOIN DEPT     d ON e.DEPTNO  = d.DEPTNO
      JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL

-- Mit WHERE und GROUP BY kombinieren
SELECT d.DNAME,
       s.GRADE,
       COUNT(*)       AS anzahl,
       AVG(e.SAL)     AS avg_gehalt
FROM   EMP     e
       JOIN DEPT     d ON e.DEPTNO = d.DEPTNO
       JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL
GROUP BY d.DNAME, s.GRADE
ORDER BY d.DNAME, s.GRADE;

6. LEFT OUTER JOIN

6.1 Grundprinzip

Der LEFT OUTER JOIN gibt alle Zeilen der linken Tabelle zurück – auch wenn es in der rechten Tabelle keine passende Zeile gibt. Fehlende Werte werden mit NULL aufgefüllt:

EMP (links)          DEPT (rechts)
─────────────        ─────────────
DEPTNO 10      →     DEPTNO 10  ✓ → Zeile wird ausgegeben
DEPTNO 20      →     DEPTNO 20  ✓ → Zeile wird ausgegeben
DEPTNO 30      →     DEPTNO 30  ✓ → Zeile wird ausgegeben
                     DEPTNO 40    → hat keine EMP-Einträge

LEFT JOIN: alle EMP-Zeilen (14) + NULLs wo kein DEPT passt

6.2 Beispiel: Alle Abteilungen, auch leere

-- DEPT ist links → alle Abteilungen erscheinen, auch ohne Mitarbeiter
SELECT d.DEPTNO,
       d.DNAME,
       e.ENAME,
       e.SAL
FROM   DEPT d
       LEFT JOIN EMP e ON d.DEPTNO = e.DEPTNO
ORDER BY d.DEPTNO, e.ENAME;

Ergebnis (Ausschnitt):

DEPTNO  DNAME       ENAME   SAL
------  ----------  ------  ----
    10  ACCOUNTING  CLARK   2450
    10  ACCOUNTING  KING    5000
    10  ACCOUNTING  MILLER  1300
    20  RESEARCH    ADAMS   1100
    ...
    40  OPERATIONS  NULL    NULL   ← Abteilung ohne Mitarbeiter!

6.3 Nur Zeilen ohne Entsprechung

-- Nur Abteilungen OHNE Mitarbeiter
SELECT d.DEPTNO, d.DNAME
FROM   DEPT d
       LEFT JOIN EMP e ON d.DEPTNO = e.DEPTNO
WHERE  e.EMPNO IS NULL;

-- Ergebnis:
-- 40   OPERATIONS

7. RIGHT OUTER JOIN

7.1 Grundprinzip

Der RIGHT OUTER JOIN gibt alle Zeilen der rechten Tabelle zurück – auch wenn es in der linken Tabelle keine passende Zeile gibt:

-- Alle Abteilungen erscheinen (DEPT ist rechts)
SELECT e.ENAME,
       e.SAL,
       d.DEPTNO,
       d.DNAME
FROM   EMP e
       RIGHT JOIN DEPT d ON e.DEPTNO = d.DEPTNO
ORDER BY d.DEPTNO;

Hinweis: Ein RIGHT JOIN lässt sich immer durch einen LEFT JOIN mit getauschter Tabellenreihenfolge ersetzen. In der Praxis wird RIGHT JOIN selten verwendet.

-- Diese beiden Abfragen liefern dasselbe Ergebnis:
FROM EMP  e RIGHT JOIN DEPT d ON e.DEPTNO = d.DEPTNO
FROM DEPT d LEFT  JOIN EMP  e ON d.DEPTNO = e.DEPTNO

8. FULL OUTER JOIN

8.1 Grundprinzip

Der FULL OUTER JOIN gibt alle Zeilen beider Tabellen zurück – egal ob eine Entsprechung existiert oder nicht:

-- Alle Mitarbeiter UND alle Abteilungen
-- Mitarbeiter ohne Abteilung: DNAME ist NULL
-- Abteilungen ohne Mitarbeiter: ENAME ist NULL
SELECT e.ENAME,
       e.DEPTNO  AS emp_deptno,
       d.DEPTNO  AS dept_deptno,
       d.DNAME
FROM   EMP  e
       FULL OUTER JOIN DEPT d ON e.DEPTNO = d.DEPTNO
ORDER BY d.DEPTNO NULLS LAST, e.ENAME;

8.2 Praxisbeispiel: Datenkonsistenzprüfung

-- Gibt es Mitarbeiter ohne gültige Abteilung ODER Abteilungen ohne Mitarbeiter?
SELECT NVL(TO_CHAR(e.EMPNO), 'kein MA')   AS empno,
       NVL(e.ENAME, '–')                   AS mitarbeiter,
       NVL(TO_CHAR(d.DEPTNO), 'keine ABT') AS dept,
       NVL(d.DNAME, '–')                   AS abteilung,
       CASE
           WHEN e.EMPNO  IS NULL THEN 'Abteilung ohne Mitarbeiter'
           WHEN d.DEPTNO IS NULL THEN 'Mitarbeiter ohne Abteilung'
           ELSE 'OK'
       END AS status
FROM   EMP  e
       FULL OUTER JOIN DEPT d ON e.DEPTNO = d.DEPTNO
WHERE  e.EMPNO IS NULL OR d.DEPTNO IS NULL;

9. SELF JOIN – Eine Tabelle mit sich selbst

9.1 Warum ein Self Join?

Die Tabelle EMP enthält in der Spalte MGR die EMPNO des Vorgesetzten – also einen Fremdschlüssel auf dieselbe Tabelle. Um den Namen des Vorgesetzten anzuzeigen, muss EMP mit sich selbst verknüpft werden:

EMP-Zeile (Mitarbeiter):    EMPNO=7369, ENAME='SMITH',  MGR=7902
EMP-Zeile (Vorgesetzter):   EMPNO=7902, ENAME='FORD',   MGR=7566

9.2 Implementierung

-- Mitarbeiter mit ihren Vorgesetzten
-- Zwei Aliase für dieselbe Tabelle!
SELECT e.ENAME          AS mitarbeiter,
       e.JOB            AS beruf,
       m.ENAME          AS vorgesetzter
FROM   EMP e
       JOIN EMP m ON e.MGR = m.EMPNO
ORDER BY m.ENAME, e.ENAME;

Ergebnis (Ausschnitt):

MITARBEITER  BERUF      VORGESETZTER
-----------  ---------  ------------
FORD         ANALYST    JONES
SCOTT        ANALYST    JONES
SMITH        CLERK      FORD
ADAMS        CLERK      SCOTT
ALLEN        SALESMAN   BLAKE
...

Beachte: KING hat keinen Vorgesetzten (MGR ist NULL). Mit INNER JOIN wird KING nicht ausgegeben. Für alle Mitarbeiter inkl. KING → LEFT JOIN verwenden!

9.3 Self Join mit LEFT JOIN für alle Mitarbeiter

-- KING wird mit LEFT JOIN ebenfalls ausgegeben
SELECT e.ENAME                             AS mitarbeiter,
       NVL(m.ENAME, '-- kein Vorgesetzter --') AS vorgesetzter,
       e.SAL,
       m.SAL                              AS gehalt_vorgesetzter
FROM   EMP e
       LEFT JOIN EMP m ON e.MGR = m.EMPNO
ORDER BY m.ENAME NULLS LAST, e.ENAME;

9.4 Mehrere Ebenen der Hierarchie

-- Mitarbeiter, ihr direkter Vorgesetzter und der Vorgesetzte des Vorgesetzten
SELECT e.ENAME    AS mitarbeiter,
       m.ENAME    AS vorgesetzter,
       mm.ENAME   AS chef_des_chefs
FROM   EMP e
       LEFT JOIN EMP m  ON e.MGR  = m.EMPNO
       LEFT JOIN EMP mm ON m.MGR  = mm.EMPNO
ORDER BY mm.ENAME NULLS LAST, m.ENAME NULLS LAST, e.ENAME;

10. NON-EQUIJOIN – Bereichsverknüpfung

10.1 Was ist ein Non-Equijoin?

Ein Non-Equijoin verwendet statt dem Gleichheitsoperator (=) einen anderen Operator in der Join-Bedingung (BETWEEN, <, >, <=, >=, !=):

10.2 Gehaltsklasse ermitteln

Die Tabelle SALGRADE enthält keine gemeinsame Schlüsselspalte mit EMP. Stattdessen wird geprüft, in welchen Bereich das Gehalt fällt:

-- Gehaltsklasse für jeden Mitarbeiter
SELECT e.ENAME,
       e.SAL,
       s.GRADE     AS gehaltsklasse,
       s.LOSAL,
       s.HISAL
FROM   EMP e
       JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL
ORDER BY s.GRADE, e.SAL;

Ergebnis:

ENAME   SAL   GEHALTSKLASSE  LOSAL  HISAL
------  ----  -------------  -----  -----
SMITH    800              1    700   1200
JAMES    950              1    700   1200
ADAMS   1100              1    700   1200
WARD    1250              2   1201   1400
MARTIN  1250              2   1201   1400
MILLER  1300              2   1201   1400
...
KING    5000              5   3001   9999

10.3 Non-Equijoin kombiniert mit INNER JOIN

-- Mitarbeiter mit Abteilung UND Gehaltsklasse
SELECT e.ENAME,
       d.DNAME,
       e.SAL,
       s.GRADE
FROM   EMP      e
       JOIN DEPT     d ON e.DEPTNO = d.DEPTNO
       JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL
WHERE  s.GRADE >= 3
ORDER BY s.GRADE DESC, e.SAL DESC;

11. Oracle-eigene JOIN-Syntax (+)

11.1 Die alte Oracle-Syntax

Vor der SQL-99-Norm hatte Oracle eine eigene JOIN-Syntax mit dem (+)-Operator. Diese wird in vielen älteren Skripten und Dokumentationen noch verwendet:

-- Alte Syntax (Oracle-spezifisch)
SELECT e.ENAME, d.DNAME
FROM   EMP e, DEPT d
WHERE  e.DEPTNO = d.DEPTNO;          -- INNER JOIN (alte Syntax)

-- LEFT OUTER JOIN (alt): (+) auf der Seite, die NULL-Werte liefern kann
SELECT e.ENAME, d.DNAME
FROM   EMP e, DEPT d
WHERE  e.DEPTNO = d.DEPTNO(+);       -- alle EMP, auch ohne DEPT
                           ───
                           Hier hat DEPT die fehlenden Werte → (+) rechts

-- RIGHT OUTER JOIN (alt): (+) auf der linken Seite
SELECT e.ENAME, d.DNAME
FROM   EMP e, DEPT d
WHERE  e.DEPTNO(+) = d.DEPTNO;      -- alle DEPT, auch ohne EMP

11.2 Gegenüberstellung alt / neu

Alte Syntax ANSI-Syntax (SQL-99)
FROM A, B WHERE A.id = B.id FROM A JOIN B ON A.id = B.id
FROM A, B WHERE A.id = B.id(+) FROM A LEFT JOIN B ON A.id = B.id
FROM A, B WHERE A.id(+) = B.id FROM A RIGHT JOIN B ON A.id = B.id
FULL OUTER JOIN: nicht möglich! FROM A FULL OUTER JOIN B ON ...

Empfehlung: Für neue Abfragen immer die ANSI-Syntax (JOIN ... ON) verwenden. Die alte Syntax kennen, um bestehende Skripte lesen zu können.

11.3 Einschränkungen der alten Syntax

-- (1) FULL OUTER JOIN ist mit (+) nicht möglich
-- (2) (+) darf nicht auf beiden Seiten stehen
-- (3) Kombination mit OR ist eingeschränkt
-- (4) Subqueries in der Join-Bedingung sind nicht möglich

-- Self Join (alte Syntax)
SELECT e.ENAME, m.ENAME AS chef
FROM   EMP e, EMP m
WHERE  e.MGR = m.EMPNO(+);    -- LEFT JOIN (KING hat keinen Chef)

12. Zusammenfassung und Ausblick

Überblick aller Join-Typen

-- INNER JOIN: nur gemeinsame Zeilen
FROM A JOIN B ON A.id = B.id

-- LEFT OUTER JOIN: alle aus A, passende aus B (sonst NULL)
FROM A LEFT JOIN B ON A.id = B.id

-- RIGHT OUTER JOIN: passende aus A (sonst NULL), alle aus B
FROM A RIGHT JOIN B ON A.id = B.id

-- FULL OUTER JOIN: alle aus A und alle aus B
FROM A FULL OUTER JOIN B ON A.id = B.id

-- CROSS JOIN: kartesisches Produkt (jede × jede)
FROM A CROSS JOIN B

-- SELF JOIN: Tabelle mit sich selbst (zwei Aliase!)
FROM EMP e JOIN EMP m ON e.MGR = m.EMPNO

-- NON-EQUIJOIN: kein = in der Bedingung
FROM EMP e JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL

Entscheidungshilfe

Welche Zeilen sollen erscheinen?
│
├── Nur Zeilen mit Entsprechung in beiden Tabellen
│     → INNER JOIN
│
├── Alle Zeilen der ersten (linken) Tabelle
│     → LEFT OUTER JOIN
│
├── Alle Zeilen der zweiten (rechten) Tabelle
│     → RIGHT OUTER JOIN
│
├── Alle Zeilen beider Tabellen
│     → FULL OUTER JOIN
│
├── Tabelle mit sich selbst (Hierarchie, Selbstreferenz)
│     → SELF JOIN (zwei Aliase!)
│
└── Verknüpfung über Bereich statt Gleichheit
      → NON-EQUIJOIN (BETWEEN, <, >)

Checkliste

Kartesisches Produkt erklären und vermeiden
INNER JOIN: Syntax, Bedeutung, Beispiel
Tabellenaliase korrekt einsetzen
Spalten bei Mehrdeutigkeit qualifizieren
LEFT / RIGHT / FULL OUTER JOIN unterscheiden
Self Join mit zwei Aliasen für dieselbe Tabelle
Non-Equijoin mit BETWEEN (EMP + SALGRADE)
Alte Oracle-Syntax (+) lesen können
Drei Tabellen mit JOIN verknüpfen
WHERE nach JOIN korrekt anwenden

Typische Prüfungsaufgaben

-- 1. Name, Beruf, Gehalt und Abteilungsname aller Mitarbeiter
SELECT e.ENAME, e.JOB, e.SAL, d.DNAME
FROM   EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO
ORDER BY d.DNAME, e.ENAME;

-- 2. Alle Abteilungen mit Anzahl Mitarbeiter (auch leere Abteilungen)
SELECT d.DNAME, COUNT(e.EMPNO) AS anzahl
FROM   DEPT d LEFT JOIN EMP e ON d.DEPTNO = e.DEPTNO
GROUP BY d.DNAME
ORDER BY anzahl DESC;

-- 3. Mitarbeiter mit ihrem Vorgesetzten (nur Mitarbeiter die einen haben)
SELECT e.ENAME AS mitarbeiter, m.ENAME AS vorgesetzter
FROM   EMP e JOIN EMP m ON e.MGR = m.EMPNO
ORDER BY m.ENAME, e.ENAME;

-- 4. Name, Gehalt, Abteilungsname und Gehaltsklasse
SELECT e.ENAME, e.SAL, d.DNAME, s.GRADE
FROM   EMP e
       JOIN DEPT     d ON e.DEPTNO = d.DEPTNO
       JOIN SALGRADE s ON e.SAL BETWEEN s.LOSAL AND s.HISAL
ORDER BY s.GRADE, e.SAL;

-- 5. Mitarbeiter deren Gehalt höher ist als das ihres Vorgesetzten
SELECT e.ENAME AS mitarbeiter, e.SAL,
       m.ENAME AS vorgesetzter, m.SAL AS chef_sal
FROM   EMP e JOIN EMP m ON e.MGR = m.EMPNO
WHERE  e.SAL > m.SAL;

Ausblick: Nächste Themen


HTL Pinkafeld – IF/IT | Oracle SQL | 11. Schulstufe

Vorheriges ThemaDQL – SELECT Nächstes ThemaSubqueries