SQL-Joins und Tabellenbeziehungen

Lerne, wie du Daten aus zusammengehörigen Tabellen in SQL verknüpfst. Folge Primär- und Fremdschlüsseln von Tabelle zu Tabelle, schreibe Inner Joins und erhalte Zeilen ohne Partner mit Left, Right und Full Outer Joins. Verknüpfe eine Tabelle mit sich selbst, bilde mit einem Cross Join alle Kombinationen und beantworte Fragen zu Viele-zu-viele-Beziehungen mithilfe von Zwischentabellen und Ketten aus drei oder mehr Tabellen. Lerne schließlich, vervielfachte Zeilen, überhöhte Summen und verlorene Zeilen zu erkennen und ein Join-Ergebnis zu prüfen, bevor du ihm vertraust. Die meisten Beispiele verwenden eine kleine Ladendatenbank, ergänzt um kleine Tabellen für Hierarchien, Viele-zu-viele-Beziehungen und Kombinationen. Jedes Beispiel zeigt seine tatsächlichen Ergebniszeilen.

AnfängerEinheit 5 von 6 in Kurs: SQL – Datenbanken abfragen mit SELECT, JOIN und GROUP BY

Was du lernst

  1. Lies, wie Tabellen durch Schlüssel verbunden sind, und erkläre, was ein Join mit ihren Zeilen macht, bevor du selbst einen schreibst.
    • Die Verknüpfungen zwischen Tabellen in einem Schema finden
      Erkenne anhand von Primär- und Fremdschlüsseln, wie Tabellen zusammenhängen, benenne jede Beziehung als Eins-zu-eins-, Eins-zu-viele- oder Viele-zu-viele-Beziehung und plane, welche Spalten ein Join abgleichen soll.
    • Erklären, was ein Join mit Zeilen macht
      Beschreibe einen Join als Paarung von Zeilen, die eine Bedingung erfüllen, sage die Breite und Länge des Ergebnisses voraus und verwende Tabellenaliase und qualifizierte Spaltennamen.
  2. Schreibe Inner Joins mit ON, USING und Bereichsbedingungen, die nur Zeilen mit einem Partner in beiden Tabellen zurückgeben, und filtere und sortiere die kombinierten Zeilen.
    • Einen Inner Join mit ON schreiben
      Verknüpfe zwei Tabellen mit JOIN ... ON über ihre Schlüsselspalten, sage genau voraus, welche Zeilen zurückgegeben werden, und ergänze Filter, Sortierung und klare Spaltennamen.
    • USING, NATURAL JOIN, Komma-Joins und Bereichsbedingungen verwenden
      Erkenne andere Schreibweisen für einen Inner Join, erkläre das Risiko jeder Variante und verknüpfe Zeilen anhand eines Bereichs statt eines gleichen Schlüsselwerts.
  3. Verwende Left, Right und Full Outer Joins, um Zeilen ohne Partner zu erhalten und fehlende Daten zu finden. Platziere jede Bedingung so, dass sie wie beabsichtigt filtert.
    • Mit LEFT JOIN alle Zeilen einer Tabelle erhalten
      Schreibe einen Left Outer Join, sage seine mit NULL aufgefüllten Zeilen voraus und finde damit Zeilen ohne Partner in einer anderen Tabelle.
    • RIGHT JOIN und FULL OUTER JOIN verwenden
      Erhalte Zeilen ohne Partner aus der rechten oder aus beiden Tabellen, schreibe einen Right Join als Left Join um und vergleiche mit einem Full Join zwei Listen.
    • Bedingungen richtig in ON oder WHERE platzieren
      Erkläre, warum sich eine Bedingung in ON und WHERE bei einem Outer Join unterschiedlich verhält, und wähle für jede Bedingung die richtige Stelle.
  4. Verwende Self Joins, um Zeilen innerhalb einer Tabelle in Beziehung zu setzen, bilde mit Cross Joins alle Kombinationen und erkenne unbeabsichtigte Cross Joins.
    • Zeilen derselben Tabelle mit einem Self Join in Beziehung setzen
      Verknüpfe eine Tabelle über zwei Aliase mit sich selbst, um Verweisen innerhalb der Tabelle zu folgen, etwa von Mitarbeitern zu ihren Vorgesetzten, und um Zeilen derselben Tabelle zu paaren.
    • Alle Kombinationen mit einem Cross Join bilden
      Paare mit CROSS JOIN jede Zeile einer Tabelle mit jeder Zeile einer anderen, sage die Größe des Ergebnisses voraus und erkenne unbeabsichtigte kartesische Produkte.
  5. Beantworte mit Zwischentabellen Fragen zu Viele-zu-viele-Beziehungen und verknüpfe drei oder mehr Tabellen in einer Abfrage, wobei du bei jedem Schritt die richtigen Zeilen erhältst.
    • Viele-zu-viele-Beziehungen über eine Zwischentabelle abfragen
      Erkläre, wie eine Zwischentabelle zwei Tabellen verbindet, und verknüpfe Tabellen über sie, um Fragen in beide Richtungen zu beantworten, auch mit Zeilen ohne Partner.
    • Drei oder mehr Tabellen in einer Abfrage verknüpfen
      Plane einen Schlüsselpfad über mehrere Tabellen, schreibe einen Join pro Verknüpfung und lies ab, wofür jede Zeile eines Ergebnisses aus mehreren Tabellen steht.
    • Zeilen ohne Partner über eine Join-Kette hinweg erhalten
      Kombiniere Outer und Inner Joins in einer Kette, ohne Zeilen zu verlieren, die du erhalten wolltest, und prüfe jeden Schritt der Kette.
  6. Erkenne, wann ein Join Zeilen vervielfacht oder verliert, behebe überhöhte Anzahlen und Summen und prüfe ein Join-Ergebnis, bevor du ihm vertraust.
    • Vervielfachte Zeilen und überhöhte Summen beheben
      Erkläre, warum Joins entlang von Eins-zu-viele-Verknüpfungen Zeilen wiederholen, und zähle und summiere Werte auf der richtigen Ebene, damit die Ergebnisse korrekt bleiben.
    • Ein Join-Ergebnis prüfen, bevor du ihm vertraust
      Sage voraus, wie viele Zeilen ein Join zurückgeben sollte, erkenne die Anzeichen häufiger Join-Fehler und gehe für jede Join-Abfrage eine kurze Prüfliste durch.

SQL-Joins einfach erklärt

6 Kapitel

1

Schlüssel und kombinierte Zeilen

Ein Join beginnt mit einer Beziehung zwischen Zeilen. Kunden- und Bestelldaten stehen in getrennten Tabellen, und Schlüssel zeigen dir, wie du sie zusammenführst. Lies das kleine Ladenschema, unterscheide Eins-zu-eins-, Eins-zu-viele- und Viele-zu-viele-Verknüpfungen und verfolge einen Pfad für einen Bericht. Sieh dann nach, wie aus passenden Paaren Ergebniszeilen werden, warum sich Namen wiederholen können und wie Aliase die Herkunft jeder ausgewählten Spalte verdeutlichen.

1.1 Schlüssel und Pfade zwischen Tabellen

Die Adresse eines Kunden gehört zum Kunden. Das Datum einer Bestellung gehört zur Bestellung. Diese Fakten in getrennten Tabellen zu speichern, verringert Wiederholungen, doch ein Bericht braucht oft Fakten aus beiden Tabellen. Ein Join verknüpft ihre Zeilen innerhalb einer Abfrage.

Schlüssel lesen

Ein Primärschlüssel identifiziert eine Zeile. Er kann aus einer Spalte oder mehreren Spalten zusammen bestehen. Ein Fremdschlüssel verweist auf einen Primärschlüssel oder einen anderen eindeutigen Schlüssel, entweder in einer anderen oder in derselben Tabelle. In der Ladendatenbank zeigt orders.customer_id auf customers.customer_id.

customer_idnamecity
1AnaDenver
2BenAustin
3ChloeDenver
4DevBoston
order_idcustomer_idorder_datetotal
10112026-03-0222,00
10212026-03-1525,50
10322026-03-2060,00
104NULL2026-03-2115,00

Die Bestellungen 101 und 102 verweisen beide auf Kunde 1, Ana. Bestellung 103 verweist auf Ben. Bestellung 104 ist eine Gastbestellung: Ihr Kundenschlüssel ist NULL, sie verweist also auf keinen Kunden. Die Bestellnummer identifiziert die Bestellung, nicht den Kunden. Ein Join von order_id mit customer_id würde Kennungen vergleichen, die nichts miteinander zu tun haben.

Die Beziehung benennen
BeziehungBedeutungWo die Verknüpfung steht
Eins zu einsJede Zeile hat höchstens einen Partner auf der anderen Seite.Ein Fremdschlüssel ist ebenfalls eindeutig, wie bei einem Ausweis pro Mitarbeiter.
Eins zu vieleEine Elternzeile kann mehrere Kindzeilen haben; jede Kindzeile hat höchstens eine Elternzeile.Der Fremdschlüssel steht auf der Viele-Seite, wie in orders.
Viele zu vieleZeilen auf beiden Seiten können mehrere Partner haben.Eine Zwischentabelle enthält je einen Fremdschlüssel zu jeder Seite.

Die Beziehung zwischen Kunden und Bestellungen ist eine Eins-zu-viele-Beziehung. Ein Kunde kann keine, eine oder mehrere Bestellungen haben. Das bedeutet nicht, dass die Kundentabelle für jeden Kauf eine Bestell-ID speichert. Jede Bestellung speichert ihren eigenen Kundenverweis.

Bei Studierenden und Kursen kann keine Seite alle Verknüpfungen mit nur einem Verweis beschreiben. Eine Zeile in enrollments erfasst ein Paar aus Studierendem und Kurs. Mehrere Einschreibungszeilen können auf denselben Studierenden und mehrere auf denselben Kurs verweisen.

Vor dem Schreiben von SQL einen Pfad verfolgen

Um die von jedem Kunden gekauften Produkte aufzulisten, folge customers → orders → order_items → products. Die Verknüpfungen verwenden zunächst customer_id, dann order_id und dann product_id. Jede Verknüpfung braucht ihre eigene Bedingung. Eine Bestellposition liefert die fehlende Verbindung zwischen einer Bestellung und einem Produkt.

Lies die Bedeutung des Schemas, nicht nur die Schreibweise der Spalten. employees.manager_id kann auf employees.emp_id verweisen, obwohl sich die Namen unterscheiden. Umgekehrt bezeichnen customers.name und products.name unterschiedliche Arten von Dingen und sollten nicht nur deshalb abgeglichen werden, weil beide name heißen.

Ein deklarierter Fremdschlüssel ist ein hilfreicher Wegweiser, aber SQL kann Tabellen auch ohne deklarierte Integritätsbedingung verknüpfen. Ein Preis kann zu einem Preisbereich passen, und zwei Mitarbeiter können zusammenpassen, weil sie denselben Vorgesetzten haben. Die Bedingung muss die für die Frage benötigte Beziehung ausdrücken.

Wichtige Erkenntnisse

  • Ein Primärschlüssel identifiziert eine Zeile; ein Fremdschlüssel verweist auf einen Primärschlüssel oder einen eindeutigen Schlüssel.
  • Der Fremdschlüssel steht auf der Viele-Seite einer Eins-zu-viele-Beziehung.
  • Eine Zwischentabelle erfasst die Paare einer Viele-zu-viele-Beziehung.
  • Folge den Verknüpfungen im Schema und gib jeder Verknüpfung eine sinnvolle Bedingung.

1.2 Wie passende Zeilen zu einem Ergebnis werden

Ein Join bildet neue Zeilen, indem er Eingabezeilen kombiniert. Beginne mit der Abgleichsregel und frag dich dann, wie viele Partner jede Zeile hat. Die Antwort bestimmt sowohl, welche Zeilen erscheinen, als auch, wie oft sich ihre Werte wiederholen.

In Paaren denken

Stelle dir bei einem Inner Join jeden Kunden neben jeder Bestellung vor. Behalte ein Paar nur, wenn o.customer_id = c.customer_id wahr ist. Bestellung 101 wird mit Ana gepaart, aber nicht mit Ben, Chloe oder Dev. Auch Bestellung 102 wird mit Ana gepaart. Ein Kunde kann daher mehrere Ergebniszeilen beitragen.

Die Bedingung kann wahr, falsch oder unbekannt sein. Eine Gleichheitsbedingung mit NULL ist unbekannt, sodass Gastbestellung 104 keinen passenden Kunden findet. Ein Outer Join erhält zusätzlich Zeilen ohne Partner von seiner gewählten Seite und füllt die Spalten des fehlenden Partners mit NULL.

Diese Vorstellung von Paaren erklärt Joins besser als überlappende Kreise. Ein Join sammelt nicht nur gemeinsame Elemente: Er bildet kombinierte Zeilen, und wiederholte Schlüssel können mehr Ergebniszeilen erzeugen, als jede der Eingaben enthält. Haben zwei Zeilen auf einer Seite und drei auf der anderen denselben Schlüssel, ergeben sich für diesen Schlüssel sechs passende Paare.

Spalten unabhängig von den Treffern auswählen

Die Kundentabelle des Ladens hat drei Spalten und die Bestelltabelle vier. Bei JOIN ... ON gibt SELECT * alle sieben zurück, einschließlich beider Exemplare von customer_id. Du kannst stattdessen nur die Felder auswählen, die der Bericht braucht:

SELECT c.name, o.order_id, o.total
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
ORDER BY o.order_id;

Das Ergebnis ist (Ana; 101; 22,00), (Ana; 102; 25,50) und (Ben; 103; 60,00). Die Schlüsselspalten ermöglichen den Abgleich, ohne in der ausgewählten Ausgabe erscheinen zu müssen. Weniger Spalten auszuwählen verändert die Breite des Ergebnisses, aber nicht, welche Eingabepaare zusammenpassen.

Tabellen kurze, klare Namen geben

In FROM customers c ist c ein Tabellenalias. Sprich die Spalten dieser Tabelle als c.name und c.customer_id an. Der Ausdruck c.name ist ein qualifizierter Spaltenname: Der Teil vor dem Punkt gibt an, welche Tabellenrolle den Wert liefert.

Beide verknüpften Tabellen enthalten customer_id. Schreibst du bei der Form mit ON nur SELECT customer_id, kann die Datenbank nicht zwischen ihnen wählen und meldet einen Fehler wegen einer mehrdeutigen Spalte. Schreibe c.customer_id oder o.customer_id, je nachdem, welchen Wert du brauchst. Qualifizierst du auch andere ausgewählte Spalten, ist ihre Herkunft ebenfalls leicht erkennbar.

AS vor einem Tabellenalias ist in PostgreSQL, SQLite, MySQL und SQL Server optional. Oracle akzeptiert es nicht, daher ist FROM customers c eine nützliche gemeinsame Schreibweise. Nachdem du einer Tabelle einen Alias gegeben hast, verwende diesen konsequent.

Die logische Reihenfolge der Abfrage lesen

FROM und seine Joins bilden die kombinierten Zeilen. WHERE filtert diese Zeilen. SELECT wählt die Ergebnisspalten aus und ORDER BY sortiert das Ergebnis. Ein Filter kann eine verknüpfte Spalte verwenden, auch wenn diese nicht ausgewählt ist. Beispielsweise kann WHERE c.city = 'Denver' einen Bericht filtern, der nur Namen und Bestellsummen anzeigt.

Ohne ORDER BY garantiert die Datenbank keine bestimmte Zeilenreihenfolge. Eine Abfrage, die heute Ana zuerst anzeigt, kann später eine andere Zeile zuerst anzeigen; das Sortieren ist eine eigene Anweisung und vom Abgleich getrennt.

Wichtige Erkenntnisse

  • Ein Inner Join erhält jedes Paar, dessen Bedingung wahr ist.
  • Wiederholte Schlüsselwerte können für eine Eingabezeile mehrere Zeilen erzeugen.
  • Aliase und qualifizierte Namen zeigen, welche Tabelle eine Spalte liefert.
  • Joins bilden Zeilen, bevor WHERE sie filtert und SELECT Spalten auswählt.
  • Verwende ORDER BY, wenn die Zeilenreihenfolge wichtig ist.
2

Inner Joins schreiben

Inner Joins beantworten Fragen, für die passende Fakten auf beiden Seiten nötig sind, etwa der Name eines Kunden neben einer Bestellung. Formuliere eine ausdrückliche Bedingung, sieh dir die tatsächlichen Ergebniszeilen an und ergänze Filter und Sortierung. Lies anschließend die Kurzformen und älteren Formen, die dir in bestehenden Abfragen begegnen können. Der Abgleich mit Bereichen führt eine andere Art von Bedingung ein: Überlappende Bereiche oder Lücken können verändern, wie viele Zeilen jeder Wert erzeugt.

2.1 Passende Zeilen mit JOIN und ON verknüpfen

Verwende einen Inner Join, wenn eine Ergebniszeile einen Partner in beiden Tabellen braucht. JOIN und INNER JOIN bedeuten dasselbe. Beide erhalten keine Zeile, die keinen Partner findet.

Die Abfrage in drei Teilen aufbauen

Benenne zuerst die Tabellen und ihre Rollen. Gib dann die Beziehung in ON an. Wähle schließlich die anzuzeigenden Spalten aus.

SELECT c.name, o.order_id, o.total
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
ORDER BY o.order_id;

Lies die Bedingung als „Der Kundenverweis der Bestellung entspricht der Kennung dieses Kunden“. Für Bestellung 101 ist der Verweis 1, sie wird also mit Ana gepaart. Auch Bestellung 102 hat den Verweis 1, und Bestellung 103 hat den Verweis 2. Das vollständige Ergebnis lautet:

nameorder_idtotal
Ana10122,00
Ana10225,50
Ben10360,00

Ana erscheint zweimal, weil sie zwei passende Bestellungen hat. Chloe und Dev haben keine und erscheinen daher nicht. Gastbestellung 104 hat einen Kundenverweis NULL, der keine Gleichheitsbedingung mit einem Kundenschlüssel erfüllt.

Die kombinierten Zeilen filtern und sortieren

Um nur Kunden aus Denver anzuzeigen, setze WHERE c.city = 'Denver' nach den Join und vor ORDER BY. Das Ergebnis lautet dann (Ana; 101; 22,00) und (Ana; 102; 25,50). Auch Chloe wohnt in Denver, aber der Inner Join hat für sie keine Zeile erzeugt.

Bei einem Inner Join ergeben sich dieselben Paare, wenn dieser Filter in ON steht. Eine gut lesbare Konvention ist, Bedingungen für den Tabellenabgleich in ON und Berichtsfilter in WHERE zu belassen. Für Outer Joins gilt diese Gleichwertigkeit nicht.

Du kannst nach einer verknüpften Spalte sortieren, die in der ausgewählten Ausgabe fehlt. Du kannst auch die Join-Schlüssel in der Ausgabe weglassen: Die obige Abfrage gleicht über customer_id ab und zeigt dabei einen Namen, eine Bestellnummer und eine Summe an. Die Rolle einer Spalte beim Abgleich ist von ihrer Rolle im Bericht getrennt.

Alle Teile eines Schlüssels abgleichen

Manche Datensätze werden durch ein Spaltenpaar identifiziert. Eine Versandposition, die auf eine Bestellposition verweist, benötigt möglicherweise sowohl die Bestell- als auch die Produktkennung:

SELECT s.order_id, s.product_id, oi.quantity
FROM shipment_lines s
JOIN order_items oi
  ON s.order_id = oi.order_id
 AND s.product_id = oi.product_id;

Beide Vergleiche müssen für einen Treffer wahr sein. Ein Abgleich nur über order_id würde jede Versandposition mit jeder Produktposition dieser Bestellung verbinden. Die Abfrage könnte erfolgreich laufen und dabei die falschen Produktmengen beschreiben.

Die Reihenfolge ändern, ohne die Bedeutung zu ändern

FROM orders o JOIN customers c ON c.customer_id = o.customer_id liefert dieselben Kunden-Bestellungs-Paare. Auch das Vertauschen der beiden Seiten von = erhält eine Gleichheitsbedingung. SELECT * kann die Spalten nach einem Tausch der Tabellen anders anordnen, und die Zeilenreihenfolge bleibt ohne Sortierung unbestimmt.

Eine weit schwerwiegendere Änderung ist ON o.order_id = c.customer_id. Beide Spalten enthalten Zahlen, daher ist dies zulässiges SQL, aber sie identifizieren unterschiedliche Dinge. In den Ladendaten gibt die Abfrage null Zeilen zurück: Die Bestell-IDs 101–104 entsprechen nie den Kunden-IDs 1–4. Prüfe die Beziehung im Schema auch dann, wenn die Datenbank keinen Syntaxfehler meldet.

Wichtige Erkenntnisse

  • JOIN bedeutet INNER JOIN: Zeilen ohne Partner auf beiden Seiten werden ausgeschlossen.
  • Schreibe die Beziehung in ON und ergänze dann Berichtsfilter und Sortierung.
  • Gleiche alle Teile eines zusammengesetzten Schlüssels mit AND ab.
  • Auch zulässiges SQL kann die falschen Spalten abgleichen.

2.2 Andere Möglichkeiten, einen Abgleich anzugeben

ON nennt eine Bedingung ausdrücklich, aber in bestehendem SQL können kürzere oder ältere Formen stehen. Lies jede Form mit der Frage, welche Paare sie erhält. Manche Formen ändern auch, wie gemeinsame Spalten in der Ausgabe erscheinen.

USING nennt den gemeinsamen Schlüssel

Wenn die Schlüsselspalten denselben Namen haben, verwendet diese Abfrage eine verkürzte Gleichheitsbedingung:

SELECT c.name, o.order_id
FROM customers c
JOIN orders o USING (customer_id)
ORDER BY o.order_id;

Sie gibt (Ana, 101), (Ana, 102) und (Ben, 103) zurück. USING (customer_id) bedeutet, die beiden Spalten customer_id zu vergleichen. Mit SELECT * gibt die Abfrage sechs Spalten zurück und zeigt den gemeinsamen Schlüssel einmal; JOIN ... ON enthält beide Schlüsselspalten der Eingaben.

Für einen zusammengesetzten Schlüssel liste beide Namen auf: USING (order_id, product_id). Jede aufgeführte Spalte muss unter diesem Namen in beiden Eingaben existieren.

PostgreSQL, SQLite, MySQL und Oracle unterstützen USING, SQL Server nicht. In Oracle darf eine in USING genannte Spalte bei einem Verweis nicht qualifiziert werden. Schreibe also SELECT customer_id, nicht SELECT c.customer_id. Andere Spalten können weiterhin ihre Tabellenaliase verwenden.

NATURAL JOIN wählt Spalten für dich

Ein NATURAL JOIN vergleicht alle Spaltennamen, die die Eingaben gemeinsam haben, verbindet diese Gleichheitsprüfungen mit AND und zeigt die gemeinsamen Spalten einmal an. PostgreSQL, SQLite, MySQL und Oracle unterstützen ihn, SQL Server nicht.

Diese automatische Wahl kann eine Abfrage unbemerkt verändern. Kunden und Bestellungen haben derzeit nur customer_id gemeinsam. Kommt zu orders eine Spalte city hinzu, verlangt ein Natural Join, dass sowohl Kunden-ID als auch Stadt übereinstimmen. Unterscheidet sich der Lieferort vom Wohnort des Kunden, kann eine zuvor passende Bestellung dadurch entfallen.

Kunden und Produkte haben beide name, aber die eine Spalte bezeichnet eine Person, die andere ein Produkt. Ihr Natural Join würde diese nicht zusammengehörigen Namen vergleichen und gibt in den Ladendaten keine Zeilen zurück. Ohne gemeinsame Spaltennamen gibt ein Natural Join stattdessen jede Kombination zurück. Verwende ON oder eine bewusst gewählte USING-Liste, damit die Abgleichsregel sichtbar bleibt.

Ältere Komma-Joins lesen
SELECT c.name, o.order_id
FROM customers c, orders o
WHERE o.customer_id = c.customer_id;

Dies gibt dieselben drei Paare wie der Inner Join zurück. Die Bedingung steht nun in WHERE. Vergisst du sie, werden alle vier Kunden mit allen vier Bestellungen gepaart, sodass 16 Zeilen entstehen. JOIN ... ON hält jede Tabelle neben ihrer eigenen Bedingung, wodurch längere Abfragen leichter zu prüfen sind.

Einen Wert mit einem Bereich abgleichen

Ein Equi-Join verwendet eine Gleichheitsbedingung. Ein Non-Equi-Join verwendet einen anderen Vergleich, etwa eine Bereichsprüfung:

SELECT p.name, b.band
FROM products p
JOIN price_bands b
  ON p.price BETWEEN b.min_price AND b.max_price;

Die Bereiche sind Budget 0,00–4,99, Standard 5,00–19,99 und Premium 20,00–999,99. Mug für 8,00 und Stapler für 12,00 passen zu Standard; Pen für 1,50 und Notebook für 4,25 passen zu Budget. Premium hat kein passendes Produkt und trägt keine Zeile bei.

BETWEEN schließt beide Bereichsgrenzen ein. Ein neuer Bereich Gift von 8,00 bis 15,00 würde für Mug und Stapler jeweils einen zweiten Treffer ergeben. Durch die Lücke zwischen 4,99 und 5,00 hätte ein Preis von 4,995 keinen Partner. Bereiche bestimmen das Ergebnis ebenso wie Schlüssel: Ein Wert kann keinen, einen oder mehrere Partner haben.

Wichtige Erkenntnisse

  • USING vergleicht die aufgeführten gleichnamigen Spalten und zeigt jeden gemeinsamen Schlüssel einmal an.
  • NATURAL JOIN hängt von jedem gemeinsamen Spaltennamen ab, sodass Schemaänderungen sein Ergebnis verändern können.
  • Ein Komma-Join braucht seine Abgleichsbedingung in WHERE.
  • Ein Non-Equi-Join kann Bereiche abgleichen; Überlappungen erzeugen zusätzliche Treffer und Lücken lassen Werte ohne Partner.
  • SQL Server verwendet ON und bietet keine Syntax für USING oder NATURAL JOIN.
3

Zeilen ohne Partner erhalten

In Berichten müssen fehlende Beziehungen oft sichtbar bleiben: Kunden ohne Bestellungen, unverkaufte Produkte oder Datensätze, die in einer von zwei Listen fehlen. Outer Joins erhalten diese Zeilen und kennzeichnen den fehlenden Partner mit NULL-Werten. Wähle, welche Seite erhalten bleiben muss, und verfolge dann, wie Bedingungen das Ergebnis verändern, je nachdem, ob sie beim Abgleich oder danach angewendet werden. Die Position einer Datumsprüfung kann darüber entscheiden, ob ein Kunde vollständig verschwindet.

Ein Bericht über „alle Kunden, einschließlich Kunden ohne Bestellungen“ braucht einen Left Outer Join. LEFT JOIN erhält jede linke Zeile. Er fügt jede passende rechte Zeile hinzu oder liefert eine Zeile mit NULL-Werten, wenn es keinen Partner gibt. Das Wort OUTER ist optional.

Der erhaltenen Tabelle folgen
SELECT c.name, o.order_id, o.total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
ORDER BY c.customer_id, o.order_id;
nameorder_idtotal
Ana10122,00
Ana10225,50
Ben10360,00
ChloeNULLNULL
DevNULLNULL

Ana liefert weiterhin zwei Zeilen. Ein Left Join reduziert die Bestellungen eines Kunden nicht auf eine. Chloe und Dev liefern jeweils genau eine Zeile, weil keiner von beiden einen Partner hat. Insgesamt gibt es fünf Zeilen: drei passende Paare und zwei Kunden ohne Partner.

Vor späteren Filtern gibt der Join mindestens so viele Zeilen zurück, wie seine linke Eingabe enthält. Zähle für jede linke Zeile ihre Partner; hat sie keine, zähle eine mit NULL aufgefüllte Zeile. Das erklärt, warum vier Kunden fünf Zeilen ergeben können.

Gastbestellung 104 fehlt. Alle Kunden zu erhalten, erhält nicht auch Bestellungen ohne Partner. Um jede Bestellung zu erhalten, beginne mit orders o LEFT JOIN customers c ON c.customer_id = o.customer_id. Die Auswahl von o.order_id, c.name ergibt dann (101, Ana), (102, Ana), (103, Ben) und (104, NULL). Chloe und Dev erscheinen nicht mehr.

Zeilen ohne Partner finden

Ein linker Anti-Join erhält nur Zeilen, für die kein Partner gefunden wurde:

SELECT c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.order_id IS NULL;

Der Left Join bildet zunächst alle fünf Zeilen. WHERE erhält dann Chloe und Dev, deren Bestellschlüssel NULL sind. Ihr fehlender Partner ist genau das, wonach die Abfrage sucht.

Wähle eine Spalte der rechten Seite, die bei einem tatsächlichen Treffer nicht NULL sein kann. Der Primärschlüssel einer Bestellung eignet sich gut für die Prüfung. Die Prüfung eines optionalen coupon_code würde auch tatsächlich passende Bestellungen ohne Gutschein erhalten und hätte daher nicht die Bedeutung „keine Bestellung“. Verwende IS NULL: = NULL wird als unbekannt ausgewertet und erhält in WHERE keine Zeilen.

Dasselbe Muster findet unverkaufte Produkte:

SELECT p.name
FROM products p
LEFT JOIN order_items oi ON oi.product_id = p.product_id
WHERE oi.order_id IS NULL;

Die Abfrage gibt (Stapler) zurück, das einzige Produkt ohne Bestellposition. Hier hat eine tatsächlich passende Position notwendigerweise eine Bestellkennung, sodass die Prüfung die fehlende Position erkennt.

Einen fehlenden Wert vor dem Ersetzen deuten

Eine mit NULL aufgefüllte Zeile eines Outer Joins bedeutet, dass kein Partner gefunden wurde. Ein gespeichertes NULL in einer tatsächlichen Bestellung kann dagegen bedeuten, dass ein Feld nicht ausgefüllt wurde. Das sind unterschiedliche Situationen, obwohl beide als NULL angezeigt werden.

COALESCE(o.total, 0) wählt das erste Argument, das nicht NULL ist. Für Chloe und Dev würde die Funktion 0 anzeigen. Das kann für einen Bericht über Ausgaben hilfreich sein, aber eine Null in einer Spalte mit der Bezeichnung „Bestellsumme“ kann eine tatsächliche Bestellung über null nahelegen. Achte darauf, dass Bezeichnung und Bedeutung des Berichts zusammenpassen.

Wichtige Erkenntnisse

  • Ein Left Join erhält die linken Zeilen und liefert NULL-Werte für fehlende rechte Partner.
  • Zähle jedes passende Paar sowie eine Zeile für jede linke Zeile ohne Partner.
  • Verwende für einen Anti-Join WHERE right_key IS NULL mit einem Schlüssel, der bei einem Treffer nicht NULL sein kann.
  • Ein Left Join erhält eine rechte Zeile ohne Partner nicht.
  • COALESCE kann die Anzeige fehlender Werte ändern; wähle eine Bezeichnung, die ihre Bedeutung klar hält.

3.2 Die rechte Seite oder beide Seiten erhalten

Manchmal stehen die benötigten Zeilen rechts in einem Join. Manchmal müssen beide Eingaben erhalten bleiben, damit fehlende Datensätze verglichen werden können. Right und Full Outer Joins machen diese Wahl ausdrücklich.

Einen Right Join als Left Join schreiben
SELECT c.name, o.order_id
FROM customers c
RIGHT JOIN orders o ON o.customer_id = c.customer_id;

Dies erhält jede Bestellung: (Ana, 101), (Ana, 102), (Ben, 103) und (NULL, 104). Die rechte Tabelle ist orders, also bleibt die Gastbestellung erhalten. Chloe und Dev sind linke Zeilen ohne Partner und bleiben nicht erhalten.

Durch Vertauschen der Eingaben erhältst du das gleichwertige orders o LEFT JOIN customers c ON o.customer_id = c.customer_id. Dieselbe ausdrückliche SELECT-Liste liefert dieselben Werte. Bei SELECT * kann sich die standardmäßige Spaltenreihenfolge ändern. Verwendest du in einem Bericht durchgehend Left Joins, lässt sich die Seite, die erhalten bleiben muss, oft leichter verfolgen.

Fehlende Zeilen aus beiden Eingaben erhalten
SELECT c.name, o.order_id
FROM customers c
FULL OUTER JOIN orders o ON o.customer_id = c.customer_id;

Das Ergebnis enthält (Ana, 101), (Ana, 102), (Ben, 103), (Chloe, NULL), (Dev, NULL) und (NULL, 104). Das sind drei passende Paare, zwei Kunden ohne Partner und eine Bestellung ohne Partner: sechs Zeilen. Bei Gastbestellung 104 sind die Kundenspalten NULL; bei Chloe und Dev sind die Bestellspalten NULL.

JoinErhaltene Zeilen ohne Partner
LEFT JOINNur linke Eingabe
RIGHT JOINNur rechte Eingabe
FULL OUTER JOINBeide Eingaben

Ein Full Join ist für den Abgleich nützlich, etwa um eine Lagerbestandsliste mit einer Inventur zu vergleichen. Passende Schlüssel erscheinen zusammen; Schlüssel, die nur auf einer Seite vorkommen, bleiben sichtbar. Ergänzt du die Ladenabfrage um WHERE c.customer_id IS NULL OR o.order_id IS NULL, bleiben nur Chloe, Dev und Bestellung 104 erhalten.

Beim Abgleich zweier Listen mit derselben Art von Schlüssel kann jeder der Eingabeschlüssel in der Ausgabe NULL sein. COALESCE(w.sku, k.sku) AS sku wählt die vorhandene Artikelnummer aus dem Lageralias w oder dem Alias k der Inventurliste. Mit einer zusammengeführten Schlüsselspalte kann der Bericht Datensätze identifizieren, die in einer der beiden Listen fehlen.

Die Syntaxunterstützung prüfen

PostgreSQL, SQL Server und Oracle unterstützen Right und Full Outer Joins. SQLite unterstützt beide ab Version 3.39.0, die 2022 veröffentlicht wurde. Ältere SQLite-Versionen lehnen sie ab. MySQL unterstützt Right Joins, hat aber keinen FULL OUTER JOIN; eine Umgehungslösung kombiniert Ergebnisse von Left und Right Joins mit UNION.

Älteres Oracle-SQL kann stattdessen die optionale Seite mit (+) in WHERE kennzeichnen. Beispielsweise erhält WHERE c.customer_id = o.customer_id(+) die Kunden und füllt fehlende Bestellspalten mit NULL, wie ein Left Join ausgehend von customers. Die Markierung gehört zu der Seite, die fehlen darf. Verwende beim Schreiben neuer Abfragen die benannten Join-Formen LEFT, RIGHT und FULL.

Wichtige Erkenntnisse

  • Ein Right Join wird zu einem Left Join, wenn die Tabellen die Plätze tauschen.
  • Die Zeilen eines Full Joins bestehen aus passenden Paaren und Zeilen ohne Partner von beiden Seiten.
  • Ein Full Join kann beim Abgleich Einträge ohne Partner sichtbar machen.
  • SQLite braucht für Right und Full Joins Version 3.39.0 oder neuer; MySQL hat kein Schlüsselwort für Full Joins.

3.3 Entscheiden, ob eine Bedingung in ON oder WHERE gehört

Ein Outer Join trennt zwei Entscheidungen: welche Paare als passend gelten und welche fertigen Ergebniszeilen der Bericht erhält. ON trifft die erste Entscheidung. WHERE trifft die zweite, nachdem Zeilen ohne Partner NULL-Werte erhalten haben.

Alle erhalten, aber ihre passenden Bestellungen einschränken

Angenommen, ein Bericht benötigt alle Kunden und nur ihre Bestellungen ab dem 10. März:

SELECT c.name, o.order_id
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id
 AND o.order_date >= '2026-03-10';

Die Datumsprüfung ist Teil des Abgleichs. Anas Bestellung 101 ist zu früh, aber Bestellung 102 erfüllt die Bedingung. Bens Bestellung 103 erfüllt sie ebenfalls. Chloe und Dev haben keinen Partner, der die Bedingung erfüllt, und erhalten daher jeweils eine mit NULL aufgefüllte Zeile. Das Ergebnis ist (Ana, 102), (Ben, 103), (Chloe, NULL) und (Dev, NULL).

Die Zeilen nach dem Join filtern

Verschiebe dieselbe Datumsprüfung nach WHERE:

SELECT c.name, o.order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.order_date >= '2026-03-10';

Nun erzeugt der Join zunächst fünf Zeilen, darunter die mit NULL aufgefüllten Zeilen für Chloe und Dev. Der Datumsvergleich ist für diese NULL-Werte unbekannt, daher entfernt WHERE sie. Auch Anas frühe Bestellung wird entfernt. Nur (Ana, 102) und (Ben, 103) bleiben erhalten.

Die WHERE-Version erzeugt dieselben passenden Zeilen wie ein Inner Join mit diesem Datumsfilter.

Die erhaltene Tabelle gezielt filtern

Auch eine linksseitige Bedingung in ON kann keine linken Zeilen entfernen. Betrachte ON o.customer_id = c.customer_id AND c.city = 'Denver'. Ana kann zu beiden Bestellungen passen, Chloe hat keine, und Ben und Dev erfüllen bei keinem möglichen Paar den Stadtteil der Bedingung. Alle vier Kunden bleiben erhalten, bei Ben, Chloe und Dev mit NULL in den Bestellspalten.

Um nur Kunden aus Denver abzufragen, setze WHERE c.city = 'Denver' nach die gewöhnliche Schlüsselbedingung. Das Ergebnis ist (Ana, 101), (Ana, 102) und (Chloe, NULL). Chloe bleibt erhalten, weil der Filter ihre eigene Stadt prüft und nicht ein fehlendes Bestellfeld.

Was die Bedingung tun sollTypische Stelle in einem Left Join
Zulässige Partner auf der rechten Seite einschränken und jede linke Zeile erhaltenON
Einschränken, welche linken Zeilen in den Bericht gehörenWHERE
Zeilen finden, deren rechter Partner fehltWHERE mit right_key IS NULL

Die Anti-Join-Prüfung gehört hinter den Join, weil sie das mit NULL aufgefüllte Ergebnis untersucht. Inner Joins haben keine erhaltenen Zeilen ohne Partner. Daher ändert das Verschieben eines Filters zwischen ON und WHERE ihre passenden Paare nicht. Lies bei der Prüfung eines Outer Joins jeden WHERE-Test für die optionale Seite und prüfe, was er mit einer mit NULL aufgefüllten Zeile macht.

Wichtige Erkenntnisse

  • ON entscheidet über die Partner; WHERE filtert fertige Ergebniszeilen.
  • Setze eine Einschränkung der rechten Seite in ON, um linke Zeilen ohne passende Partner zu erhalten.
  • Setze Berichtseinschränkungen für die linke Seite in WHERE.
  • Ein rechtsseitiger Vergleich in WHERE entfernt mit NULL aufgefüllte Zeilen, wenn er unbekannt ist.
  • Die IS NULL-Prüfung des Anti-Joins wird bewusst nach dem Join ausgeführt.
4

Self Joins und Cross Joins

Dieselbe Join-Technik kann zwei Rollen in einer Tabelle verbinden oder alle Kombinationen zweier Tabellen bilden. Abfragen zu Mitarbeitern und Vorgesetzten brauchen Aliase, die die Rollen klar unterscheiden. Für Kollegenpaare ist außerdem eine Regel für Selbstpaarungen und umgekehrte Duplikate nötig. Cross Joins erzeugen bewusst alle Möglichkeiten, etwa Größen und Farben. Wenn du ihre Größe vorhersagst, erkennst du leichter, wann diese Vervielfachung beabsichtigt war und wann eine Bedingung fehlt.

4.1 Zwei Rollen für eine Tabelle

Der Vorgesetzte eines Mitarbeiters ist ebenfalls ein Mitarbeiter. Ein Self Join liest dieselbe Tabelle unter verschiedenen Aliasen, sodass eine Zeile den Mitarbeiter und eine andere den Vorgesetzten darstellen kann. Er verwendet die übliche Join-Syntax; ein Schlüsselwort SELF JOIN gibt es nicht.

Die Rollen vor den Spalten benennen

Die Mitarbeiterdaten lauten:

emp_idnamemanager_id
1GraceNULL
2Hassan1
3Iris1
4Jamal2
SELECT e.name AS employee, m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.emp_id;

e liefert die Mitarbeiterzeile. Ihre manager_id zeigt auf die emp_id des Vorgesetzten in der Rolle m. Hassan zeigt auf 1 und wird daher mit Grace gepaart; auch Iris wird mit Grace gepaart. Jamal zeigt auf 2 und wird mit Hassan gepaart. Das Ergebnis ist (Hassan, Grace), (Iris, Grace) und (Jamal, Hassan).

Grace hat keinen Vorgesetzten. Ihre manager_id ist NULL, daher schließt der Inner Join sie aus. Ersetzt du JOIN durch LEFT JOIN, kommt (Grace, NULL) hinzu und es entstehen vier Zeilen. Unterschiedliche Aliase ermöglichen es der Datenbank, die Rollen auseinanderzuhalten, obwohl beide Eingaben aus derselben gespeicherten Tabelle stammen.

Die Frage in der anderen Richtung stellen

Um Personen zu finden, die niemanden führen, beginne mit der Rolle des Vorgesetzten und suche nach einem fehlenden Mitarbeiter:

SELECT m.name
FROM employees m
LEFT JOIN employees e ON e.manager_id = m.emp_id
WHERE e.emp_id IS NULL;

Dies gibt (Iris) und (Jamal) zurück. Zu Grace passen Hassan und Iris; zu Hassan passt Jamal. Iris und Jamal haben keine direkt unterstellten Mitarbeiter. Die Prüfung des Mitarbeiterschlüssels nach dem Join findet ihren fehlenden Partner.

Ein dritter Alias folgt einer weiteren Ebene. employees e JOIN employees m ON e.manager_id = m.emp_id JOIN employees g ON m.manager_id = g.emp_id gibt bei Auswahl ihrer Namen (Jamal, Hassan, Grace) zurück. Jede zusätzliche Rolle folgt einer weiteren Verknüpfung. Eine feste Abfrage erreicht eine feste Anzahl von Ebenen; eine Hierarchie beliebiger Tiefe braucht eine rekursive Abfrage.

Kollegen einmal paaren

Dieselbe Tabelle kann auch Kollegenpaare liefern:

SELECT a.name, b.name
FROM employees a
JOIN employees b
  ON a.manager_id = b.manager_id
 AND a.emp_id < b.emp_id;

Hassan und Iris haben denselben Vorgesetzten mit der Kennung 1. Die Kleiner-als-Prüfung schließt aus, dass eine Person mit sich selbst gepaart wird, und erhält nur eine Reihenfolge jedes Paares. Das Ergebnis ist (Hassan, Iris).

Mit der Gleichheitsbedingung für den Vorgesetzten allein hat das Ergebnis fünf Zeilen: Hassan–Hassan, Hassan–Iris, Iris–Hassan, Iris–Iris und Jamal–Jamal. Graces NULL-Vorgesetztenschlüssel passt zu nichts, auch nicht zu einem anderen NULL. Ersetzt du < durch <>, werden Selbstpaarungen ausgeschlossen, aber sowohl (Hassan, Iris) als auch (Iris, Hassan) erhalten. Wähle <, wenn die Frage jedes ungeordnete Paar einmal verlangt.

Wichtige Erkenntnisse

  • Verwende für die unterschiedlichen Rollen in einem Self Join verschiedene Aliase.
  • Gleiche die manager_id eines Mitarbeiters mit der emp_id der Vorgesetztenrolle ab.
  • Ein Left Self Join kann die oberste Person einer Hierarchie erhalten.
  • Jeder zusätzliche Self Join folgt einer weiteren festen Ebene.
  • Bei Paaren derselben Gruppe entfernt < Selbstpaarungen und umgekehrte Duplikate; <> entfernt nur Selbstpaarungen.

4.2 Jede mögliche Kombination

Ein Cross Join bildet ohne Abgleichsbedingung jedes Zeilenpaar. Das ist nützlich, wenn die Frage nach Möglichkeiten fragt, etwa nach jeder Kombination aus Größe und Farbe, die ein Geschäft vorrätig halten könnte.

Die Kombinationsliste erstellen

sizes enthält S, M und L. colors enthält Red und Blue.

SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c;

Die sechs Paare sind (S, Red), (S, Blue), (M, Red), (M, Blue), (L, Red) und (L, Blue). Jede Größe erscheint neben beiden Farben. Das sind die Ergebniszeilen; ihre Anzeigereihenfolge ist ohne ORDER BY nicht garantiert.

Bei zwei Eingaben multiplizierst du ihre Zeilenanzahlen. Drei Größen und zwei Farben ergeben sechs Zeilen. Kommt eine dritte Tabelle mit vier Optionen hinzu, hat das Ergebnis 24 Zeilen. Ist eine Eingabe leer, lässt sich keine vollständige Kombination bilden und das Ergebnis hat null Zeilen.

Mit einem vollständigen Berichtsraster beginnen

Verkaufsdatensätze zeigen nur Kombinationen, die aufgetreten sind. Um jedes Geschäft in jedem Monat anzuzeigen, bilde zunächst mit stores CROSS JOIN months ein Raster. Füge dann mit einem Left Join passende Verkaufsdatensätze hinzu:

SELECT s.store_id, m.month, x.total
FROM stores s
CROSS JOIN months m
LEFT JOIN sales x
  ON x.store_id = s.store_id
 AND x.month = m.month;

Das Raster erhält ein Geschäfts-Monats-Paar auch dann, wenn es keinen Verkauf gibt; in x.total steht dann NULL. Beide Schlüsselteile sind wichtig: Ein Abgleich nur über das Geschäft würde auch dessen Verkäufe aus anderen Monaten hinzufügen. Der Cross Join bestimmt, welche Kombinationen der Bericht zeigen muss, und der Left Join liefert die dazu verfügbaren Fakten.

Einen unbeabsichtigten Cross Join erkennen

FROM customers, orders ohne Verknüpfungsbedingung bildet aus den vier Kunden und vier Bestellungen 16 Paare. Ana wird mit ihren eigenen Bestellungen, Bens Bestellung und der Gastbestellung gepaart. Bei jedem Kunden geschieht dasselbe. Das ist nur sinnvoll, wenn tatsächlich jede Kunden-Bestellungs-Kombination gewünscht ist.

Eine hohe Zeilenanzahl ist ein Hinweis, aber prüfe auch die Paarungen. Bei 1.000 Kunden und 1.000 Produkten erzeugt ein beabsichtigter Cross Join 1.000.000 Zeilen. Ein Join mit einer falschen, aber einschränkenden Bedingung kann auch ein kleineres, falsches Ergebnis zurückgeben. Vergleiche die Anzahl und die Bedeutung jedes Paares mit der Frage.

Gleichwertige Formen erkennen

CROSS JOIN, ein Komma-Join ohne Abgleichsbedingung und ein Inner Join mit ON 1 = 1 erhalten alle jedes Paar. SQLite und MySQL akzeptieren auch ein einfaches JOIN ohne ON und behandeln es als Cross Join; PostgreSQL verlangt für einen einfachen Join ON oder USING. Schreibe CROSS JOIN, wenn jede Kombination beabsichtigt ist.

DISTINCT entfernt identische ausgewählte Zeilen, keine falschen Beziehungen. Paart ein unbeabsichtigter Cross Join Ana mit Bens Bestellung, bleiben diese Werte eine eigenständige Zeile. Ergänze die fehlende Bedingung, statt einen Teil der wiederholten Ausgabe zu verbergen.

Wichtige Erkenntnisse

  • Ein Cross Join gibt jede Kombination zurück; multipliziere die Zeilenanzahlen der Eingaben.
  • Eine leere Eingabe macht das kartesische Produkt leer.
  • Ein Cross Join kann ein vollständiges Raster für einen späteren Left Join erstellen.
  • Eine fehlende Abgleichsbedingung kann einen unbeabsichtigten Cross Join erzeugen.
  • DISTINCT entfernt keine falschen Paarungen.
5

Zwischentabellen und längere Pfade

Manche Berichte brauchen einen Weg durch mehrere Tabellen, bevor sich die angefragten Fakten zusammenführen lassen. Einschreibungszeilen verbinden Studierende mit Kursen, und Bestellpositionen verbinden Bestellungen mit Produkten. Folge jeweils einem Schlüssel, behalte im Blick, wofür jede Ergebniszeile steht, und wähle, welche Verknüpfungen erforderlich sind. Ein Left Join am Anfang einer Kette kann seine Zeilen ohne Partner bei einem späteren Schritt verlieren. Deshalb muss der gesamte Pfad die für den Bericht vorgesehenen Datensätze erhalten.

5.1 Einer Viele-zu-viele-Verknüpfung folgen

Ein Studierender kann mehrere Kurse belegen, und ein Kurs kann mehrere Studierende haben. Eine Zwischentabelle erfasst diese Viele-zu-viele-Verknüpfungen als einzelne Paare. Sie wird auch Brückentabelle, Verknüpfungstabelle oder assoziative Tabelle genannt.

Eine Verknüpfung pro Zeile lesen

Die Beispieldaten enthalten die Studierenden 1 Mia, 2 Noah und 3 Omar; die Kurse 10 Algebra, 20 Biology und 30 Chemistry; sowie die Einschreibungspaare (1, 10), (1, 20) und (2, 10).

student_idcourse_id
110
120
210

Studierender 1 erscheint zweimal, weil Mia zwei Kurse belegt. Kurs 10 erscheint zweimal, weil Algebra zwei Studierende hat. Keine der Spalten muss für sich genommen eindeutig sein. Das Paar kann einen zusammengesetzten Primärschlüssel bilden, PRIMARY KEY (student_id, course_id), der verhindert, dass derselbe Studierende zweimal in denselben Kurs eingeschrieben wird.

Eine Verknüpfung kann eigene Fakten haben. enrolled_on gehört zur Einschreibung, weil es beschreibt, wann ein bestimmter Studierender einem bestimmten Kurs beigetreten ist. Ebenso beschreibt order_items.quantity, wie viel von einem bestimmten Produkt zu einer bestimmten Bestellung gehört.

Die Zwischentabelle mit zwei Joins durchlaufen
SELECT s.name, c.title
FROM students s
JOIN enrollments e ON e.student_id = s.student_id
JOIN courses c ON c.course_id = e.course_id;

Die erste Bedingung fügt die Einschreibungszeilen jedes Studierenden hinzu. Die zweite ersetzt den Kursverweis jeder Einschreibung durch Fakten aus der Kurstabelle. Das vollständige Ergebnis ist (Mia, Algebra), (Mia, Biology) und (Noah, Algebra). Jede Zeile steht für eine Einschreibung.

Keine der beiden Tabellen an den Enden enthält einen Schlüssel vom Studierenden zum Kurs. Ein Abgleich mit s.student_id = c.course_id würde nicht zusammengehörige Kennungen vergleichen und die Einschreibungsdaten überspringen. Die Zwischentabelle liefert die Beziehung.

Derselbe Pfad funktioniert in beide Richtungen. Ergänze WHERE c.title = 'Algebra', um (Mia, Algebra) und (Noah, Algebra) zu erhalten. Ergänze stattdessen WHERE s.name = 'Mia', um (Mia, Algebra) und (Mia, Biology) zu erhalten. Die Verknüpfungen bleiben gleich; der Filter wählt aus, welche davon die Frage beantworten.

Personen oder Kurse ohne Verknüpfungen einbeziehen

Beginne bei der Seite, die erhalten bleiben muss. students s LEFT JOIN enrollments e ON e.student_id = s.student_id erhält Omar mit NULL in den Einschreibungsspalten. Um Kurstitel anzuzeigen und ihn dabei zu erhalten, muss auch der spätere Join von enrollments zu courses die fehlende Einschreibung erhalten.

Um Kurse zu finden, die niemand belegt, verwende die Kursseite und einen Anti-Join:

SELECT c.title
FROM courses c
LEFT JOIN enrollments e ON e.course_id = c.course_id
WHERE e.student_id IS NULL;

Dies gibt (Chemistry) zurück. Bei einer tatsächlich passenden Einschreibung ist student_id Teil des Primärschlüssels und kann nicht NULL sein. Die Prüfung erkennt daher die fehlende Verknüpfung.

Speichere eine Beziehung pro Zeile der Zwischentabelle. Eine Textliste wie „10,20“ in einem Studierendenfeld kann durch einen Gleichheitsvergleich nicht mit den einzelnen Kurs-IDs 10 und 20 abgeglichen werden. Getrennte Paare ermöglichen es jeder Join-Bedingung, einen Verweis mit einem Schlüssel zu vergleichen.

Wichtige Erkenntnisse

  • Eine Zeile der Zwischentabelle erfasst ein Paar und kann Fakten über diese Beziehung enthalten.
  • Die beiden Fremdschlüssel können einen zusammengesetzten Schlüssel bilden, der doppelte Paare verhindert.
  • Zwei Joins verbinden die Tabellen an den Enden über die Zwischentabelle.
  • Beginne beim Endpunkt, der erhalten bleiben muss, wenn du fehlende Beziehungen suchst.

5.2 Ein Pfad über vier Tabellen

Für einen längeren Join gilt dieselbe Regel wie für einen Join aus zwei Tabellen: Füge die nächste Tabelle mit einer sinnvollen Bedingung hinzu. Verfolge vor dem Schreiben der Abfrage die Schlüssel und entscheide, was eine Ergebniszeile darstellen soll.

Die detaillierten Ladendaten hinzufügen
product_idnameprice
1Mug8,00
2Pen1,50
3Notebook4,25
4Stapler12,00

Die Bestellpositionen (order_id, product_id, quantity) sind (101, 1, 2), (101, 2, 4), (102, 3, 6), (103, 1, 6), (103, 2, 8) und (104, 2, 10). Jede Position verbindet eine Bestellung mit einem Produkt und erfasst eine Menge.

Für die Frage „Was hat jeder Kunde gekauft?“ folge customers → orders → order_items → products. Die Schlüssel entlang des Pfads sind Kunden-ID, Bestell-ID und Produkt-ID. Vier Tabellen entlang dieser Kette brauchen drei Verknüpfungen.

Jeweils eine neue Tabelle hinzufügen
SELECT c.name, o.order_id, p.name AS product,
       oi.quantity, oi.quantity * p.price AS line_total
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
JOIN order_items oi ON oi.order_id = o.order_id
JOIN products p ON p.product_id = oi.product_id
ORDER BY o.order_id, p.product_id;

Jedes ON verweist auf die neu eingeführte Tabelle und eine bereits verfügbare. Produkte werden über Bestellpositionen hinzugefügt, nicht direkt über Kunden. Das Ergebnis lautet:

nameorder_idproductquantityline_total
Ana101Mug216,00
Ana101Pen46,00
Ana102Notebook625,50
Ben103Mug648,00
Ben103Pen812,00

Der erste Join schließt Gastbestellung 104 aus, weil ihr Kundenverweis NULL ist. Die verbleibenden drei Bestellungen enthalten fünf Positionen, daher hat das Endergebnis fünf Zeilen. Bei Bestellung 101 kosten zwei Tassen 16,00 und vier Stifte 6,00, passend zur Bestellsumme von 22,00.

Wissen, was eine Zeile zählt

Eine Ergebniszeile steht für eine Bestellposition. Ana und Bestellung 101 erscheinen zweimal, weil diese Bestellung zwei Produkte hat. Wiederholte Kundennamen sind daher zu erwarten. Werden diese Zeilen gezählt, zählt man Positionen, keine unterschiedlichen Kunden oder Bestellungen.

Ein Filter kann auf jede verknüpfte Tabelle verweisen. Ergänzt du vor ORDER BY ein WHERE p.name = 'Pen', bleiben (Ana; 101; Pen; 4; 6,00) und (Ben; 103; Pen; 8; 12,00) erhalten. Kein Produktfilter kann die Gastbestellung zurückholen, die bereits bei der Kundenverknüpfung ausgeschlossen wurde.

Jede Verknüpfung sichtbar halten

Bei einer Kette von Inner Joins kann sich die Reihenfolge der Tabellen ändern, ohne die passenden Kombinationen zu verändern, sofern jede Bedingung nur auf bereits eingeführte Tabellen verweist. Am leichtesten zu lesen ist es meist, beim Gegenstand des Berichts zu beginnen und dessen Schlüsseln zu folgen.

Eine fehlende Bedingung kann in SQLite oder MySQL ein Zwischenergebnis vervielfachen, da diese ein einfaches JOIN ohne ON akzeptieren. PostgreSQL und SQL Server lehnen diese Syntax ab. Eine fehlende Bedingung in einer Abfrage mit Kommaschreibweise kann bei diesem Schritt ebenfalls jede Kombination erzeugen.

Manchmal erfüllt eine Tabelle zwei Rollen. Ein Flugbericht kann airports als dep über dep.code = f.from_code und erneut als arr über arr.code = f.to_code verknüpfen. Unterschiedliche Aliase geben den Abflug- und Ankunftsdaten getrennte Plätze im Ergebnis.

Wichtige Erkenntnisse

  • Ergänze eine Join-Bedingung für jede Verknüpfung im Tabellenpfad.
  • Jedes ON darf die neue Tabelle und bereits eingeführte Tabellen verwenden.
  • Bestimme, wofür eine Ergebniszeile steht, bevor du Werte zählst oder addierst.
  • Eine Tabelle kann unter verschiedenen Aliasen erscheinen, wenn der Bericht unterschiedliche Rollen braucht.

5.3 Optionale Zeilen über eine Kette hinweg erhalten

Ein Left Join erhält Zeilen bei einem Schritt. Spätere Joins und Filter wirken weiterhin auf das Ergebnis dieses Schritts. Um eine Elternzeile ohne Partner über einen längeren Pfad zu erhalten, verfolge bei jedem Schritt, was mit ihren mit NULL aufgefüllten Spalten geschieht.

Sehen, wo eine erhaltene Zeile verschwindet
SELECT c.name, o.order_id, oi.product_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
JOIN order_items oi ON oi.order_id = o.order_id;

Der erste Schritt bildet fünf Zeilen: Anas zwei Bestellungen, Bens Bestellung und je eine mit NULL aufgefüllte Zeile für Chloe und Dev. Beim nächsten Schritt sind die o.order_id-Werte von Chloe und Dev NULL. Sie können die Gleichheitsbedingung mit einem Bestellpositionsschlüssel nicht erfüllen, sodass der Inner Join sie entfernt. Die Abfrage gibt fünf Bestellpositionszeilen zurück und verliert beide Kunden ohne Bestellungen.

Den optionalen Pfad erhalten
SELECT c.name, o.order_id, oi.product_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
LEFT JOIN order_items oi ON oi.order_id = o.order_id;

Nun erhält auch der zweite Join diese mit NULL aufgefüllten Zeilen. Das Ergebnis enthält (Ana, 101, 1), (Ana, 101, 2), (Ana, 102, 3), (Ben, 103, 1), (Ben, 103, 2), (Chloe, NULL, NULL) und (Dev, NULL, NULL): sieben Zeilen.

Wenn spätere Joins von Spalten einer optionalen Tabelle abhängen, müssen sie gewöhnlich Left Joins bleiben, um fehlende Partner zu erhalten. Ein späterer Inner Join über Spalten einer erforderlichen Tabelle hat eine andere Rolle. Untersuche daher die tatsächliche Abhängigkeit in jeder Bedingung.

Derselben Regel durch eine Zwischentabelle folgen
SELECT s.name, c.title
FROM students s
LEFT JOIN enrollments e ON e.student_id = s.student_id
LEFT JOIN courses c ON c.course_id = e.course_id;

Dies gibt (Mia, Algebra), (Mia, Biology), (Noah, Algebra) und (Omar, NULL) zurück. Wird der letzte Join zu einem Inner Join, entfernt er Omar, weil seine fehlende Einschreibung zu keinem Kurs passen kann.

Klammern bieten eine weitere Möglichkeit, die Gruppierung auszudrücken: students s LEFT JOIN (enrollments e JOIN courses c ON c.course_id = e.course_id) ON e.student_id = s.student_id. Die passenden Einschreibungs-Kurs-Paare bilden die optionale Gruppe; der Outer Join fügt diese Gruppe jedem Studierenden hinzu und erhält Omar.

Spätere Filter und die Join-Richtung prüfen

Ergänzt du die Studierendenabfrage, die nur Left Joins enthält, um WHERE c.title = 'Algebra', bleiben nur Mia und Noah in Algebra. Der Vergleich ist für Omars NULL-Kurstitel unbekannt. Das beantwortet „Wer belegt Algebra?“, aber nicht mehr „Zeige alle Studierenden und ihre Kurse“. Eine IS NULL-Prüfung verhält sich anders, weil sie einen fehlenden Wert bewusst akzeptiert.

Ein späterer Right Join ändert die erhaltene Seite erneut: Er erhält die neu hinzugefügte rechte Tabelle, und frühere Zeilen ohne Partner können verschwinden. Stelle die Tabelle, die erhalten bleiben muss, an den Anfang und füge optionale Pfade mit Left Joins hinzu, wenn dies den Bericht klar ausdrückt.

Baue die Abfrage Join für Join auf und prüfe sie nach jedem Schritt. Notiere sowohl die Zeilenanzahl als auch die verbleibenden Schlüssel. Eine sinkende Anzahl kann verlorene Zeilen ohne Partner aufdecken; ein unerwarteter Anstieg kann auf einen fehlenden Schlüsselteil hinweisen. Manche Anzahlen bleiben unverändert, wenn Zeilen sowohl verloren gehen als auch vervielfacht werden. Prüfe deshalb auch repräsentative Schlüssel.

Wichtige Erkenntnisse

  • Jeder Join wirkt auf das bisher aufgebaute Ergebnis.
  • Ein Inner Join über den NULL-Schlüssel einer optionalen Tabelle entfernt Zeilen ohne Partner.
  • Halte spätere abhängige Verknüpfungen optional, wenn ihre fehlenden Zeilen erhalten bleiben müssen.
  • Ein späterer WHERE-Vergleich kann weiterhin Zeilen entfernen, die durch Left Joins erhalten wurden.
  • Prüfe nach jedem Schritt die Anzahl und die erhaltenen Schlüssel.
6

Zuverlässige Anzahlen und Ergebnisse

Wiederholte Werte sind oft eine korrekte Folge eines Joins, können aber die Anzahlen und Summen eines Berichts verfälschen. Verfolge eine Bestellsumme, die durch Detailzeilen wiederholt wird, wähle die richtige Kennung zum Zählen und unterscheide ein nützliches DISTINCT von einem verborgenen Join-Fehler. Prüfe einen Bericht dann anhand der vorhergesagten Treffer, vollständiger Schlüssel, des NULL-Verhaltens und einheitlicher Schlüsselformate, bevor du seiner plausibel aussehenden Ausgabe vertraust.

6.1 Auf der richtigen Ebene zählen und addieren

Ein Join kann korrekt sein, während ein Aggregat über seinem Ergebnis falsch ist. Die entscheidende Frage ist, was eine Zeile nach dem Join darstellt. Ein Wert, der einmal pro Bestellung gespeichert ist, kann in einer Liste von Bestellpositionen mehrfach erscheinen.

Eine wiederholte Bestellsumme verfolgen

Ana hat Bestellung 101 über 22,00 und Bestellung 102 über 25,50. Die Summe der beiden Bestellungen beträgt 47,50. Bestellung 101 hat zwei Positionen, daher wiederholt der Join mit order_items die 22,00 zweimal; Bestellung 102 hat eine Position. Addiert man die wiederholten Werte, ergibt sich 69,50.

SELECT c.customer_id, c.name, SUM(o.total) AS spent
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id
GROUP BY c.customer_id, c.name;

GROUP BY fasst die Zeilen jedes Kunden zusammen und SUM addiert die Werte dieser Gruppe. Diese Abfrage gibt (1; Ana; 47,50) und (2; Ben; 60,00) zurück. Ein zusätzlicher Join mit den Bestellpositionen vor der Gruppierung würde Anas Summe auf 69,50 und Bens Summe auf 120,00 erhöhen. Die Summen der beiden Kunden würden zusammen 189,50 statt 107,50 betragen.

Über alle vier Bestellungen einschließlich der Gastbestellung 104 führt ein direkter Join der Bestellungen mit ihren Positionen dazu, dass SUM(o.total) 204,50 statt 122,50 zurückgibt. Dieser Fan-out entsteht durch die Eins-zu-viele-Verknüpfung, nicht durch einen Syntaxfehler.

Fakten auf ihrer gespeicherten Ebene summieren

Summiere für Bestellsummen die Bestellungen, ohne die Detailtabelle hinzuzufügen. Berechne für eine Summe der Positionsbeträge den Wert jeder einzelnen Position:

SELECT SUM(oi.quantity * p.price) AS sales
FROM order_items oi
JOIN products p ON p.product_id = oi.product_id;

Die sechs Positionsbeträge sind 16,00, 6,00, 25,50, 48,00, 12,00 und 15,00. Zusammen ergeben sie 122,50, die Summe aller vier Bestellungen. Jedes Produkt aus Menge und Preis gehört zu einer Position und wird daher einmal addiert.

Tatsächliche Treffer zählen

Nach dem Join von Kunden mit Bestellungen und Positionen belegt Ana drei Zeilen. COUNT(*) zählt diese Positionen; COUNT(DISTINCT o.order_id) zählt ihre zwei unterschiedlichen Bestellungen.

Nach einem einfachen Left Join von Kunden zu Bestellungen zählt COUNT(*) eine mit NULL aufgefüllte Zeile für Chloe und eine für Dev. Zähle stattdessen den optionalen Bestellschlüssel:

SELECT c.customer_id, c.name, COUNT(o.order_id) AS orders
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
GROUP BY c.customer_id, c.name;

Dies gibt (1, Ana, 2), (2, Ben, 1), (3, Chloe, 0) und (4, Dev, 0) zurück. COUNT(column) ignoriert NULL-Werte; COUNT(*) zählt Zeilen.

Zwei Viele-Seiten multiplizieren sich gegenseitig

Hat ein Kunde drei Bestellungen und zwei Supportanfragen, erzeugt ein unabhängiger Join beider Kindtabellen mit diesem Kunden sechs Zeilen. Jede Bestellung wird mit jeder Anfrage gepaart. Einfache Zählungen eines der beiden Kindschlüssel ergeben jeweils sechs. Zähle unterschiedliche Kindschlüssel, um drei und zwei zu erhalten, oder fasse die Kindtabellen getrennt zusammen.

DISTINCT c.customer_id, c.name ist für eine eindeutige Kundenliste nützlich. Der Schlüssel verhindert, dass verschiedene Kunden mit demselben Namen zusammengefasst werden. Er behebt keine fehlende Join-Bedingung. Auch SUM(DISTINCT o.total) ist unsicher: Es fasst zwei getrennte Bestellungen zusammen, die zufällig denselben Betrag haben.

Wichtige Erkenntnisse

  • Eins-zu-viele-Joins wiederholen Elternwerte; summiere einen Wert auf der Ebene, auf der er gespeichert ist.
  • COUNT(*) zählt Zeilen; COUNT(column) überspringt NULL-Werte.
  • COUNT(DISTINCT key) zählt nach einem Fan-out unterschiedliche Kennungen, die nicht NULL sind.
  • Zwei unabhängige Joins auf der Viele-Seite können sich gegenseitig vervielfachen.
  • SUM(DISTINCT amount) kann verschiedene Datensätze mit gleichen Beträgen zusammenfassen.
  • Behalte in einer Liste eindeutiger Entitäten einen identifizierenden Schlüssel.

6.2 Treffer prüfen, bevor du einem Bericht vertraust

Eine Abfrage kann laufen und trotzdem die falschen Beziehungen beschreiben. Sage vor der Verwendung eines Join-Ergebnisses voraus, was erhalten bleiben sollte, wie oft jeder Schlüssel erscheinen sollte und was eine Ergebniszeile bedeuten sollte.

Die Zeilenanzahl vorhersagen

Wenn der Kundenverweis einer Bestellung zu einem eindeutigen Kundenschlüssel passt, hat jede Bestellung höchstens einen Kunden als Partner. Ein Inner Join gibt daher höchstens eine Zeile pro Bestellung zurück. In den Ladendaten haben drei von vier Bestellungen einen Kunden, also gibt der Inner Join zwischen Kunden und Bestellungen drei Zeilen zurück.

Von der Kundenseite aus gibt ein Left Join die drei passenden Paare sowie je eine Zeile für Chloe und Dev zurück: fünf Zeilen. Ein Cross Join der vier Kunden und vier Bestellungen ergibt 16. Diese Vorhersagen bieten unterschiedliche Prüfungen für unterschiedliche Join-Typen; die Anzahl der Tabellen allein bestimmt die Zeilenanzahl nicht.

Die Struktur eines falschen Ergebnisses untersuchen
AnzeichenWas du prüfen solltest
Jede linke Zeile wird mit jeder rechten Zeile gepaartFehlende oder immer wahre Bedingung
Keine Treffer oder Paarungen nicht zusammengehöriger EntitätenFalsche Spalten oder nicht kompatible Schlüsselwerte
Ein logischer Datensatz hat mehrere PartnerEin unvollständiger Schlüssel, ein doppelter Nachschlageschlüssel oder eine erwartete Eins-zu-viele-Verknüpfung
Elternzeilen ohne Kindzeilen verschwindenEin Inner Join oder ein Filter für die optionale Seite an späterer Stelle der Abfrage

Ein Abgleich nur über store_id, wenn Datensätze durch (store_id, month) identifiziert werden, vermischt verschiedene Monate. Gleiche jeden Bestandteil mit AND ab. Eine Abfrage, die zufällig funktioniert, solange für ein Geschäft ein Monat vorhanden ist, kann fehlschlagen, sobald ein zweiter Monat geladen wird.

Fehlende Werte von falschen Schlüsseln unterscheiden

Bei gewöhnlicher Gleichheit passen NULL-Schlüssel nicht zusammen, auch nicht NULL mit NULL. Ein Join von Bestellungen mit sich selbst über customer_id ergibt vier Paare aus Anas zwei Bestellungen und eines aus Bens Bestellung, also fünf Zeilen. Die Gastbestellung trägt keines bei. Ein Outer Join ist nötig, wenn eine Zeile mit fehlendem Verweis erhalten bleiben muss.

Doppelte Nachschlagewerte vervielfachen nur die Treffer für diese Werte. Kommt ein Ländercode zweimal in einer Nachschlagetabelle vor, erhält jeder Kunde mit diesem Code zwei Partnerzeilen. Codes, die einmal vorkommen, ergeben weiterhin einen Partner. Prüfe eine Nachschlagetabelle, deren Werte eindeutig sein sollten, mit:

SELECT code, COUNT(*) AS copies
FROM countries
GROUP BY code
HAVING COUNT(*) > 1;

GROUP BY fasst die Zeilen jedes Codes zusammen; HAVING erhält Gruppen, deren Anzahl größer als eins ist. Würde die gesamte Nachschlagetabelle zweimal geladen, verdoppelten sich die Zeilen jedes passenden Kunden.

Prüfe auch Schlüsseltypen und -formate. Der Text „0042“ und die Zahl 42 können je nach Datenbank zu unterschiedlichem Verhalten führen: kein Treffer, ein Typfehler oder eine automatische Umwandlung. SQLite kann eine TEXT-Spalte mit „0042“ mit einer INTEGER-Spalte mit 42 abgleichen. Verwende einheitliche Schlüsseltypen und -formate oder eine ausdrückliche Umwandlung, die zur beabsichtigten Bedeutung passt.

Die Anforderungen des Berichts durchgehen

Frag dich, welche Tabelle alle Zeilen behalten muss. Verfolge ihren vollständigen Schlüsselpfad und prüfe jede Bedingung anhand des Schemas. Entscheide, warum jede Verknüpfung ein Inner oder Outer Join ist, und prüfe dann, ob jeder Filter beim Abgleich oder danach wirken soll. Vergleiche die Zeilenanzahlen nach jedem Schritt und untersuche eine bekannte Zeile mit einem Partner, eine Zeile ohne Partner und eine Zeile mit mehreren Partnern. Prüfe schließlich, ob jede Anzahl und Summe die beabsichtigte Art von Datensatz misst.

Wichtige Erkenntnisse

  • Sage Anzahlen anhand der Beziehung und des Join-Typs voraus.
  • Prüfe jeden Bestandteil eines zusammengesetzten Schlüssels.
  • Gewöhnliche Gleichheit behandelt NULL-Schlüssel nie als passend.
  • Doppelte Nachschlageschlüssel vervielfachen die betroffenen Treffer.
  • Halte Typen und Formate verknüpfter Schlüssel einheitlich.
  • Prüfe erhaltene Kennungen ebenso wie Summen und Zeilenanzahlen.

SQL-Joins: Beispiele

6 Interaktive Lektionen

1

Von Schemaverknüpfungen zu verknüpften Zeilen

10 Schritte
Lies die Schlüssel des Ladenschemas, sage passende Paare voraus und mache die Herkunft jeder Spalte deutlich.
  1. 1
    EinführungMit der Frage des Berichts beginnen

    Ein Bericht braucht Kundennamen neben Bestellsummen, aber diese Fakten stehen in verschiedenen Tabellen. Ein Join führt die zusammengehörigen Zeilen zusammen.

    Finde zuerst die Schlüsselverknüpfung. Stelle dir dann die Paare vor, die sie zulässt. Diese Reihenfolge hilft dir, das Ergebnis vor dem Schreiben von SQL vorherzusagen: Ein Name kann sich wiederholen, weil es mehrere passende Bestellungen gibt, und eine Zeile kann verschwinden, weil sie keinen Partner hat.

  2. 2
    BeispielKunden- und Bestellschlüssel lesen

    Die Kunden sind 1 Ana, 2 Ben, 3 Chloe und 4 Dev. Die Bestellungen 101 und 102 verweisen auf Kunde 1; Bestellung 103 verweist auf Kunde 2. Bestellung 104 ist eine Gastbestellung mit einem Kundenverweis NULL.

    Die Verknüpfung lautet orders.customer_id → customers.customer_id. Die Bestellnummer identifiziert einen Kauf, während der Kundenverweis den zugehörigen Kunden identifiziert. Ein Vergleich dieser beiden unterschiedlichen Arten von IDs würde die Zugehörigkeit nicht ausdrücken.

  3. 3
    ErklärungDen Verweis auf die Viele-Seite setzen

    Ein Kunde kann mehrere Bestellungen aufgeben. Jede Bestellung speichert einen Kundenverweis, daher ist orders die Viele-Seite der Verknüpfung.

    Bei einer Eins-zu-eins-Verknüpfung ist dieser Verweis außerdem eindeutig. Bei Viele-zu-viele-Verknüpfungen, etwa wenn Studierende Kurse belegen, erfasst eine Zwischentabelle die Paare. Diese Strukturen zeigen dir, welchem Pfad ein Bericht folgen muss und wo mehrere Partner möglich sind.

  4. 4
    HerausforderungDen fehlenden Pfad finden

    Du brauchst die Produkte, die jeder Kunde gekauft hat. Das Schema verbindet customers mit orders, orders mit order_items und order_items mit products. Kannst du order_items überspringen und die Bestell-ID direkt mit der Produkt-ID vergleichen?

    ---reveal---

    Nein. Diese IDs identifizieren unterschiedliche Dinge. Folge customers → orders → order_items → products. Jede order_items-Zeile erfasst ein Produkt in einer bestimmten Bestellung und liefert damit die Verknüpfung, die dem direkten Vergleich fehlt.

  5. 5
    BeispielDie ersten Paare bilden

    Wende o.customer_id = c.customer_id an. Bestellung 101 passt zu Ana, weil beide Kundenwerte 1 sind. Bestellung 102 bildet ein weiteres Paar mit Ana und Bestellung 103 passt zu Ben.

    Die Ergebnispaarungen sind (Ana, 101), (Ana, 102) und (Ben, 103). Chloe und Dev haben keine Partner. Gastbestellung 104 hat einen Kundenschlüssel NULL, daher ist ihre Gleichheitsbedingung unbekannt und liefert keinen Treffer.

  6. 6
    KernaussageEine Linie für jeden Treffer

    Stelle dir eine Linie zwischen jeder Kundenzeile und jeder dazu passenden Bestellzeile vor. Jede Linie wird zu einer Ergebniszeile. Ana hat zwei Linien, daher erscheint ihr Name zweimal.

    Dieses Bild funktioniert auch, wenn sich Schlüssel auf beiden Seiten wiederholen: Zwei linke und drei rechte Zeilen mit einem Schlüssel erzeugen sechs Linien. Überlappende Kreise können diese einzelnen Paarungen nicht zeigen oder erklären, wie ein Join länger als jede der Eingaben wird.

  7. 7
    TippDie Herkunft einer Spalte angeben

    Gib den Tabellenverweisen Aliase, etwa customers c und orders o. Schreibe c.name für den Kundennamen und o.total für die Bestellsumme.

    Beide Eingaben haben customer_id. Bei JOIN ... ON ist die Auswahl dieses Namens allein mehrdeutig; qualifiziere ihn als c.customer_id oder o.customer_id. SELECT * enthält alle sieben Eingabespalten, einschließlich beider Exemplare des Schlüssels. Wählst du nur benötigte Spalten aus, wird der Bericht schmaler.

  8. 8
    ErklärungDer Abgleich kommt vor dem Filtern

    Lies die logische Reihenfolge als Joins, dann WHERE, dann SELECT und dann ORDER BY. Ein Filter kann eine verknüpfte Spalte verwenden, die der Bericht nicht anzeigt.

    Filterst du beispielsweise die Kunden-Bestellungs-Paare mit c.city = 'Denver', bleiben Anas zwei Bestellungen erhalten. Chloe wohnt auch in Denver, aber ein Inner Join hat für sie keine Zeile erzeugt. Ein späterer Filter kann eine beim Abgleich ausgeschlossene Zeile nicht zurückholen.

  9. 9
    HerausforderungEin Ergebnis mit wiederholtem Schlüssel vorhersagen

    Eine Tabelle mit Anmeldungen hat zwei Zeilen mit dem Standortschlüssel 8. Eine Standort-Nachschlagetabelle hat versehentlich drei Zeilen mit dem Schlüssel 8. Alle anderen Schlüssel fehlen. Wie viele Zeilen gibt ihr Inner Join mit Gleichheitsbedingung zurück, und ändert die Auswahl nur des Schlüssels diese Anzahl?

    ---reveal---

    Es werden sechs Zeilen zurückgegeben: Jede Anmeldung passt zu allen drei Nachschlagezeilen. Die Auswahl nur des Schlüssels macht jede Zeile schmaler, erhält aber sechs Zeilen, sofern nicht eine separate Operation wie DISTINCT wiederholte ausgewählte Werte entfernt.

  10. 10
    ZusammenfassungErst die Beziehung, dann die Zeilen lesen

    Finde den Schlüsselpfad, bevor du die Ergebnisspalten auswählst. Eins-zu-viele-Verknüpfungen können Elternwerte wiederholen; eine Zwischentabelle bildet eine Viele-zu-viele-Verknüpfung ab.

    Frag dich für jedes Paar, ob die Bedingung wahr ist. Prüfe dann, wie viele Partner jede Zeile hat. Verwende Aliase, um die Herkunft der Spalten zu unterscheiden, und halte beim Erklären des Ergebnisses den Abgleich vom späteren Filtern und Sortieren getrennt.

2

Inner Joins erstellen und lesen

11 Schritte
Schreibe eine vollständige Abfrage für passende Zeilen und vergleiche anschließend Kurzformen und Bereichsbedingungen.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungAuf beiden Seiten einen Partner verlangen
  2. 2
    BeispielDie Schlüsselbedingung schreiben
  3. 3
    BeispielAlle drei Ergebniszeilen lesen
  4. 4
    HerausforderungEinen Kundenfilter hinzufügen
  5. 5
    TippDie vollständige Kennung abgleichen
  6. 6
    ErklärungEine Kurzform für gleiche Namen verwenden
  7. 7
    HerausforderungBeachten, was NATURAL verändert
  8. 8
    VerbindungEinen älteren Komma-Join lesen
  9. 9
    BeispielPreise Preisbereichen zuordnen
  10. 10
    HerausforderungEine Überlappung und eine Lücke beurteilen
  11. 11
    ZusammenfassungDie Bedingung hinter der Syntax lesen
3

Zeilen ohne Partner erhalten, ohne sie durch Filter zu verlieren

14 Schritte
Wähle die erhaltene Seite und verfolge ON und WHERE in Outer-Join-Ergebnissen.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEntscheiden, welche Datensätze bleiben müssen
  2. 2
    BeispielJeden Kunden erhalten
  3. 3
    HerausforderungDie zu erhaltende Seite ändern
  4. 4
    TippDen Schlüssel des fehlenden Partners prüfen
  5. 5
    ErklärungEinen Right Join als umgekehrten Left Join lesen
  6. 6
    BeispielDatensätze ohne Partner von beiden Seiten erhalten
  7. 7
    HerausforderungZwei neue Schlüssellisten abgleichen
  8. 8
    TippDie Unterstützung für Outer Joins prüfen
  9. 9
    BeispielPassende Bestellungen in ON einschränken
  10. 10
    BeispielDie Datumsprüfung nach WHERE verschieben
  11. 11
    HerausforderungDie linke Tabelle gezielt filtern
  12. 12
    VerbindungEntscheiden, was eine angezeigte Null bedeutet
  13. 13
    HerausforderungAlle mit kürzlich aktiven Mitarbeitern erhalten
  14. 14
    ZusammenfassungAbgleichen und Filtern getrennt halten
4

Vorgesetzten folgen und Kombinationen bilden

11 Schritte
Verwende Rollenaliase für Self Joins und unterscheide dann beabsichtigte und unbeabsichtigte kartesische Produkte.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungRollen oder Möglichkeiten wählen
  2. 2
    BeispielDie Berichtswege lesen
  3. 3
    HerausforderungDie Person an der Spitze erhalten
  4. 4
    VerbindungEine weitere Ebene aufsteigen
  5. 5
    BeispielKollegenpaare einmal bilden
  6. 6
    BeispielSechs Hemdvarianten bilden
  7. 7
    HerausforderungDie Auswirkung einer weiteren Eingabe vorhersagen
  8. 8
    KernaussageEin vollständiges Berichtsraster erstellen
  9. 9
    TippDie fehlende Bedingung ergänzen
  10. 10
    HerausforderungPaarungsregeln mit der Produktgröße verbinden
  11. 11
    ZusammenfassungJeder Paarung einen klaren Zweck geben
5

Einer Zwischentabelle folgen und einen längeren Pfad erhalten

14 Schritte
Verfolge Einschreibungen und Bestellpositionen und erhalte dann fehlende Partner über abhängige Verknüpfungen hinweg.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungDen Pfad zu den Fakten planen
  2. 2
    BeispielDie Einschreibungsverknüpfungen lesen
  3. 3
    BeispielDie Zwischentabelle in zwei Schritten durchlaufen
  4. 4
    HerausforderungEinen Kurs ohne Studierende finden
  5. 5
    ErklärungDen Pfad durch die Ladendaten erweitern
  6. 6
    BeispielBestellung 101 in Positionen aufteilen
  7. 7
    BeispielDie übrigen Kaufzeilen lesen
  8. 8
    HerausforderungDie Produktverknüpfung wählen
  9. 9
    BeispielSehen, wie ein späterer Join Kunden entfernt
  10. 10
    BeispielDie fehlende Zeile weiterführen
  11. 11
    HerausforderungDen Studierenden ohne Einschreibung erhalten
  12. 12
    VerbindungEine optionale Gruppe ausdrücklich bilden
  13. 13
    HerausforderungDen Filter des fertigen Berichts prüfen
  14. 14
    ZusammenfassungDen gesamten Pfad prüfen
6

Überhöhte Summen beheben und das Ergebnis prüfen

12 Schritte
Wähle den richtigen Datensatz zum Zählen oder Summieren und untersuche anschließend Probleme mit Schlüsseln und Zeilenanzahlen.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungDie gemessene Größe benennen
  2. 2
    BeispielDie Wiederholung einer Bestellsumme verfolgen
  3. 3
    TippEinen Wert auf seiner eigenen Ebene summieren
  4. 4
    HerausforderungEine Korrektur anhand des Betrags verwerfen
  5. 5
    BeispielEine Kennung oder einen Platzhalter zählen
  6. 6
    KernaussageZwei Kindlisten vervielfachen sich
  7. 7
    ErklärungDie Größenordnung vor dem Ausführen vorhersagen
  8. 8
    HerausforderungEinen unvollständigen Schlüssel finden
  9. 9
    TippDie Nachschlagetabelle und das Schlüsselformat prüfen
  10. 10
    BeispielFehlende Schlüssel nicht durch Gleichheit abgleichen
  11. 11
    HerausforderungEine korrekte Kennzahl für den Bericht wählen
  12. 12
    ZusammenfassungBedeutung und Anzahlen prüfen

SQL-Joins: Übungsaufgaben

50 Übungsfragen in 5 Sets

Set 1: Beziehungen lesen und passende Zeilen auswählen10 Übungsfragen

Frage 1 von 10

Ein Bibliotheksmitglied kann viele Ausleihen haben und jede Ausleihe gehört zu einem Mitglied. Wo sollte der Fremdschlüssel für das Mitglied gespeichert werden?
  1. In der Mitgliedertabelle
  2. In der Ausleihtabelle
  3. In beiden Tabellen
  4. In einer separaten Tabelle
Antwort zeigenAntwort ausblenden
Antwort: B
Jede Ausleihe muss ihr einziges Mitglied identifizieren. Daher gehört der Fremdschlüssel in loans, auf die Viele-Seite. Ein Mitglied kann dann von mehreren Ausleihzeilen referenziert werden. Ein einzelner Ausleihverweis in members würde nicht alle Ausleihen abbilden, die das Mitglied haben kann.

Frage 2 von 10

Zwei Zeilen in Tabelle a haben den Schlüssel 7. Drei Zeilen in Tabelle b haben den Schlüssel 7. Dies sind die einzigen Zeilen. Wie viele Zeilen gibt a JOIN b ON a.k = b.k zurück?
  1. 2
  2. 3
  3. 5
  4. 6
Antwort zeigenAntwort ausblenden
Antwort: D
Jede der zwei linken Zeilen passt zu allen drei rechten Zeilen, sodass sechs unterschiedliche Zeilenpaare entstehen. Ein Inner Join erhält jedes passende Paar, auch wenn sich Schlüsselwerte wiederholen. Würde man nur die drei rechten Zeilen zählen, bliebe unberücksichtigt, dass jede zwei linke Partner hat.

Frage 3 von 10

rentals.customer_ref verweist auf customers.customer_id. Ausleihen haben außerdem ihre eigene rental_id. Welche ON-Bedingung verknüpft jede Ausleihe r mit ihrem Kunden c?
  1. r.customer_ref = c.customer_id
  2. r.rental_id = c.customer_id
  3. r.customer_ref = r.rental_id
  4. c.customer_id = c.customer_id
Antwort zeigenAntwort ausblenden
Antwort: A
Der Fremdschlüssel customer_ref identifiziert den Kunden, der zur Ausleihe gehört, und muss daher mit dem Kundenschlüssel verglichen werden. Die Ausleih-ID identifiziert eine Ausleihe und hat eine andere Bedeutung. Ähnlich aussehende numerische IDs reichen nicht aus, um eine Verknüpfung herzustellen.

Frage 4 von 10

Die Tabellen a und b enthalten jeweils account_id und region. Zuvor hatten sie für einen Natural Join nur account_id gemeinsam; region wurde gerade zu b hinzugefügt. Warum kann ein zuvor passendes Paar verschwinden?
  1. Seine Regionen stimmen überein, aber seine Konto-IDs unterscheiden sich.
  2. Die neue gemeinsame Spalte lässt alle Paare übereinstimmen.
  3. Seine Konto-IDs stimmen überein, aber seine Regionen unterscheiden sich.
  4. Die neue Spalte lässt gemeinsame IDs zweimal erscheinen.
Antwort zeigenAntwort ausblenden
Antwort: C
NATURAL JOIN vergleicht jeden gemeinsamen Spaltennamen, sodass neben account_id nun auch region übereinstimmen muss. Ein Paar mit gleichen Konto-IDs, aber unterschiedlichen Regionen passt nicht mehr. Der Join erhält ein Paar nicht allein deshalb, weil eine gemeinsame Spalte übereinstimmt.

Frage 5 von 10

Die Teams sind (1, North) und (2, South). Die Spiele (match_id, team_id) sind (81, 1) und (82, 1). Welche Namen erscheinen vor dem Filtern bei einem LEFT JOIN von der Teamseite zu den Spielen?
  1. North einmal; South einmal
  2. North zweimal; South einmal
  3. North zweimal; South nie
  4. North zweimal; South zweimal
Antwort zeigenAntwort ausblenden
Antwort: B
North hat zwei passende Spielzeilen und erscheint daher zweimal. South hat keinen Partner, aber der Left Join erhält es einmal mit NULL in den Spielspalten. Eine Zeile pro Team zu zählen würde die zusätzliche Zeile durch das zweite Spiel von North übersehen.

Frage 6 von 10

Liste A hat die eindeutigen Schlüssel 2 und 5. Liste B hat die eindeutigen Schlüssel 5 und 8. Welche Paare ergeben sich aus einem FULL OUTER JOIN über Schlüsselgleichheit?
  1. (2, NULL), (5, 5)
  2. (5, 5), (NULL, 8)
  3. (2, NULL), (5, 5), (NULL, 8)
  4. (2, 2), (5, 5), (8, 8)
Antwort zeigenAntwort ausblenden
Antwort: C
Schlüssel 5 passt zwischen den beiden Eingaben. Schlüssel 2 existiert nur in A und Schlüssel 8 nur in B, daher bleibt jeder mit NULL für seinen fehlenden Partner erhalten. Würde man beide Spalten mit dem jeweiligen Schlüssel ohne Partner füllen, würde man Werte aus einer Zeile erfinden, die auf dieser Seite nie vorhanden war.

Frage 7 von 10

Die Mitarbeiter sind (id, manager_id): (10, NULL), (11, 10), (12, 10). Ein Self Join verwendet a.manager_id = b.manager_id AND a.id < b.id. Welches ID-Paar wird zurückgegeben?
  1. (11, 12)
  2. (10, 11)
  3. (11, 11)
  4. (12, 11)
Antwort zeigenAntwort ausblenden
Antwort: A
Die Mitarbeiter 11 und 12 haben denselben Vorgesetzten 10 und 11 ist kleiner als 12. Die Kleiner-als-Bedingung schließt Selbstpaarungen und das umgekehrte Paar aus. Mitarbeiter 10 hat eine Vorgesetzten-ID NULL, die daher nicht der Vorgesetzten-ID von Mitarbeiter 11 oder 12 entsprechen kann.

Frage 8 von 10

Ein Studio listet 4 Räume und 3 Sitzungstermine auf. Wie viele Zeilen erzeugt ein CROSS JOIN der Listen?
  1. 7
  2. 4
  3. 3
  4. 12
Antwort zeigenAntwort ausblenden
Antwort: D
Jeder der vier Räume wird mit jedem der drei Termine gepaart, sodass zwölf Kombinationen entstehen. Vier und drei zu addieren würde Eingabeeinträge zählen, keine Raum-Termin-Paare. Bei einem Cross Join schränkt keine Abgleichsbedingung die Kombinationen ein.

Frage 9 von 10

authors(author_id) und books(book_id) sind durch book_authors(author_id, book_id) verbunden. Welcher Pfad findet die Bücher eines Autors?
  1. authors → books über gleiche IDs
  2. authors → books mit CROSS JOIN
  3. book_authors → authors über book_id
  4. authors → book_authors → books
Antwort zeigenAntwort ausblenden
Antwort: D
Die Zwischentabelle erfasst, welcher Autor zu welchem Buch gehört. Verknüpfe authors mit book_authors über die Autoren-ID und book_authors mit books über die Buch-ID. Die direkte Gleichsetzung der IDs an den Endpunkten vergleicht unterschiedliche Arten von Kennungen und ignoriert die gespeicherten Autorenbeziehungen.

Frage 10 von 10

sales(store_id, month) enthält (6, March) und (6, April). targets(store_id, month) enthält dieselben zwei Paare, jeweils einmal. Eine Abfrage verknüpft nur über die Geschäfts-ID und gibt vier Zeilen zurück. Welche Korrektur ergibt einen Zielwert pro Verkauf?
  1. DISTINCT nur auf die Geschäfts-ID anwenden.
  2. Die Gleichheit der beiden Monatsspalten zu ON hinzufügen.
  3. Den Inner Join durch einen Left Join ersetzen.
  4. Mit LIMIT 2 nur die ersten zwei Zeilen behalten.
Antwort zeigenAntwort ausblenden
Antwort: B
Die Geschäfts-ID allein lässt den Verkauf jedes Monats zu beiden Zielmonaten passen, wodurch vier Paare entstehen. Wird auch der Monat abgeglichen, bleiben nur März–März und April–April. Ein Left Join würde weiterhin alle vier Treffer erzeugen, weil das Erhalten von Zeilen einen unvollständigen Schlüssel nicht vervollständigt.
Set 2: Zeilen ohne Partner erhalten und Tabellenpfaden folgen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Jedes Inventarobjekt kann höchstens ein aktives Etikett haben und jedes Etikett gehört zu höchstens einem Inventarobjekt. Welche Beziehung beschreibt die beiden Tabellen?
  1. Eins zu viele
  2. Viele zu viele
  3. Eins zu eins
  4. Alle Paarungen
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

invoices enthält (invoice_id, client_id): (301, 9), (302, NULL), (303, 12). clients hat die eindeutigen IDs 9 und 12. Welche Rechnungs-IDs bleiben bei einem Inner Join über die Kunden-ID erhalten?
  1. 301 und 303
  2. 301, 302 und 303
  3. Nur 302
  4. Nur 301
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Ein Schreibtisch kann mehrere Reservierungen haben. Reservierungs-IDs können nicht NULL sein, aber note darf NULL sein. Welche WHERE-Prüfung findet nach desks LEFT JOIN reservations nur Schreibtische ohne Reservierung?
  1. r.note IS NULL
  2. r.reservation_id = NULL
  3. r.note IS NOT NULL
  4. r.reservation_id IS NULL
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein Bericht muss jede Abteilung zeigen und nur aktive Mitarbeiter hinzufügen. Er beginnt mit departments d LEFT JOIN employees e ON e.department_id = d.department_id. Wohin gehört e.active = 1?
  1. Als Bedingung in WHERE
  2. Als zusätzliche AND-Bedingung in ON
  3. Als Ausdruck in ORDER BY
  4. Als Ersatz für den Schlüsselvergleich
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein CROSS JOIN kombiniert eine Tabelle mit 8 Zeilen und eine leere Tabelle. Wie viele Zeilen werden zurückgegeben?
  1. 8
  2. 1
  3. 9
  4. 0
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

memberships(member_id, club_id) erfasst den Beitritt eines Mitglieds zu einem Verein. Wohin gehört joined_on, das Datum dieser bestimmten Mitgliedschaft?
  1. In memberships
  2. In members
  3. In clubs
  4. In eine kommagetrennte Vereinsliste
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Bericht folgt clients → invoices → lines → services. Jeder Pfeil ist eine Schlüsselverknüpfung und jede service-Zeile ist durch die Service-ID eindeutig. Was stellt eine Detailzeile des Ergebnisses dar, wenn jede Verknüpfung einen Treffer hat?
  1. Einen Kunden
  2. Eine Rechnung
  3. Eine Rechnungsposition
  4. Eine Leistung im Katalog
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Die Filialen sind 1 und 2. Filiale 1 hat einen Auftrag mit zwei Aufgabenzeilen; Filiale 2 hat keine Aufträge. Eine Kette verwendet branches LEFT JOIN jobs und danach INNER JOIN tasks über den Auftragsschlüssel. Wie ändert sich die Zeilenanzahl, wenn der Aufgaben-Join zu LEFT wird?
  1. Sie bleibt bei 2.
  2. Sie steigt von 2 auf 3.
  3. Sie steigt von 2 auf 4.
  4. Sie sinkt von 3 auf 2.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Ein Projekt hat zwei Rechnungen über jeweils 40,00. Die erste Rechnung hat zwei Positionen und die zweite drei. Was ergeben SUM(total) und SUM(DISTINCT total) nach dem Join von Rechnungen mit Positionen?
  1. 80,00 und 80,00
  2. 200,00 und 80,00
  3. 200,00 und 40,00
  4. 80,00 und 40,00
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine Regions-Nachschlagetabelle sollte eine Zeile pro code haben. Manche verknüpften Kunden erscheinen zweimal. Welche Diagnoseabfrage findet wiederholte Nachschlagecodes?
  1. SELECT code, COUNT(*) FROM regions GROUP BY code HAVING COUNT(*) > 1;
  2. SELECT DISTINCT code FROM regions;
  3. SELECT code, COUNT(*) FROM regions GROUP BY code HAVING COUNT(*) = 1;
  4. SELECT code FROM regions WHERE code IS NULL;
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 3: Filter, Paarungen und wiederholte Werte verfolgen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Join mit ON verbindet eine Tabelle mit 4 Spalten und eine Tabelle mit 3 Spalten. Wie breit ist SELECT *, bevor Spalten entfernt werden?
  1. 4 Spalten
  2. 3 Spalten
  3. 12 Spalten
  4. 7 Spalten
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Betrag von 25,00 wird mit BETWEEN low AND high Preisbereichen zugeordnet. Die Bereiche sind (0.00, 25.00) und (25.00, 50.00). Wie viele passende Bereichszeilen erzeugt der Betrag?
  1. 0
  2. 1
  3. 2
  4. 3
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Eine Abfrage verwendet suppliers s RIGHT JOIN deliveries d ON d.supplier_id = s.supplier_id und wählt ausdrücklich s.name, d.delivery_id aus. Wie kann sie mit LEFT JOIN dieselben Paare erhalten?
  1. suppliers s LEFT JOIN deliveries d ON d.supplier_id = s.supplier_id
  2. deliveries d LEFT JOIN suppliers s ON d.supplier_id = s.supplier_id
  3. deliveries d JOIN suppliers s ON d.supplier_id = s.supplier_id
  4. suppliers s FULL JOIN deliveries d ON d.supplier_id = s.supplier_id
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Die Geschäfte A und B bleiben bei einem Left Join zu Besuchen erhalten. A hat einen Besuch vor einem Stichtag; B hat keinen. ON erhält nur Besuche am oder nach dem Stichtag. Welche Geschäfte bleiben, wenn diese Einschränkung ohne weitere Änderungen nach WHERE verschoben wird?
  1. Weder A noch B
  2. Nur A
  3. Nur B
  4. Sowohl A als auch B
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Drei Mitarbeiter haben die unterschiedlichen IDs 21, 22 und 23 und alle die Vorgesetzten-ID 5. Ein Self Join gleicht gleiche Vorgesetzten-IDs und unterschiedliche Mitarbeiter-IDs mit <> ab. Wie viele Zeilen werden zurückgegeben und wie viele würde < zurückgeben?
  1. 3 mit <>; 3 mit <
  2. 6 mit <>; 3 mit <
  3. 9 mit <>; 6 mit <
  4. 6 mit <>; 6 mit <
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Flugzeile hat from_code und to_code, die beide auf airports.code verweisen. Wie sollte ein Bericht beide Flughafennamen abrufen?
  1. Airports einmal über from_code verknüpfen und den Namen für die Ankunft wiederverwenden.
  2. Airports einmal über beide Code-Gleichheiten mit AND verknüpfen.
  3. Airports mit einem Cross Join verknüpfen und nur nach from_code filtern.
  4. Airports zweimal mit Aliasen für Abflug und Ankunft verknüpfen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Alle Techniker müssen mit ihren optionalen Einsätzen und Standorten erscheinen. Die Abfrage verknüpft Einsätze mit einem Left Join und danach Standorte mit einem Inner Join über die Standort-ID des Einsatzes. Warum verschwinden Techniker ohne Einsatz?
  1. Ihre Einsatzschlüssel NULL können beim Inner Join keinen Standort finden.
  2. Ein Left Join kann nur einen Techniker ohne Einsatz erhalten.
  3. Die Auswahl einer Standortspalte entfernt jede Zeile ohne Partner.
  4. Der Standortalias verbirgt den Primärschlüssel des Technikers.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Team hat keine Aufgaben. Was gibt COUNT(t.task_id) nach teams LEFT JOIN tasks und einer Gruppierung nach Team zurück, wenn Aufgaben-IDs nicht NULL sein können?
  1. 1
  2. NULL
  3. 0
  4. Die Anzahl der Teams
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Ein Autor hat 2 Artikel und 3 Auszeichnungen, die jeweils unabhängig voneinander mit ihm verknüpft sind. Eine Abfrage verknüpft beide Kindtabellen über die Autoren-ID mit Inner Joins und gruppiert nach Autor. Was ergeben COUNT(article_id) und COUNT(DISTINCT award_id)?
  1. 2 und 3
  2. 6 und 6
  3. 6 und 3
  4. 3 und 2
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Ein Bericht beginnt mit shipments s LEFT JOIN carriers c über einen passenden Transportunternehmerschlüssel. Eine Sendung hat keinen passenden Transportunternehmer und ein Transportunternehmer hat keine Sendungen. Welcher Datensatz ohne Partner bleibt erhalten?
  1. Nur der Transportunternehmer
  2. Nur die Sendung
  3. Beide Datensätze ohne Partner
  4. Keiner der Datensätze ohne Partner
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 4: Unvollständige Verknüpfungen und fehlende Zeilen untersuchen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

workers.supervisor_ref verweist auf workers.worker_id. Mitarbeiter haben auch eine Spalte name. Was sollte den Mitarbeitera­lias w mit dem Vorgesetztenalias s verknüpfen?
  1. w.supervisor_ref = s.worker_id
  2. w.worker_id = s.supervisor_ref
  3. w.name = s.name
  4. w.worker_id = s.worker_id
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Eine Join-Bedingung ist für 4 mögliche Zeilenpaare wahr, für 3 falsch und für 2 unbekannt. Wie viele Zeilen gibt der Inner Join zurück?
  1. 6
  2. 4
  3. 7
  4. 9
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Eine Abfrage verknüpft Zahlungen p über die Konto-ID mit Konten a durch einen Inner Join. Sie wählt nur a.name, p.amount aus. Muss die Konto-ID ebenfalls ausgewählt werden, damit der Join funktioniert?
  1. Ja; beide Konto-ID-Spalten müssen ausgewählt werden.
  2. Ja; mindestens eine Konto-ID-Spalte muss ausgewählt werden.
  3. Nein; SELECT fügt beide Konto-IDs automatisch hinzu.
  4. Nein; ON kann Spalten verwenden, die in SELECT fehlen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Die Tabellen a(id, label) und b(id, label) haben die Zeilen (1, red), (2, blue) beziehungsweise (1, red), (2, green). Wie viele Zeilen werden mit JOIN ... USING (id) und wie viele mit NATURAL JOIN zurückgegeben?
  1. 1 mit USING; 1 mit NATURAL
  2. 2 mit USING; 2 mit NATURAL
  3. 2 mit USING; 1 mit NATURAL
  4. 4 mit USING; 2 mit NATURAL
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Die Regionen East und West haben jeweils ein Büro. Ein LEFT JOIN, der alle Regionen erhält, enthält AND r.name = 'East' in ON. Welche Zeilen erscheinen bei der Auswahl von Region und Büro?
  1. East mit seinem Büro; West mit NULL
  2. East mit seinem Büro; West fehlt
  3. East mit seinem Büro; West mit seinem Büro
  4. East mit NULL; West mit NULL
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Die Mitarbeiter sind (id, boss_id): (31, NULL), (32, 31), (33, 32), (34, 32). Welche ID-Tripel geben Inner Joins über e.boss_id = m.id und m.boss_id = g.id zurück?
  1. Nur (32, 31, NULL)
  2. (31, 32, 33) und (31, 32, 34)
  3. (32, 31, NULL), (33, 32, 31), (34, 32, 31)
  4. (33, 32, 31) und (34, 32, 31)
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

customers → orders → order_lines → products ist ein Schlüsselpfad. Ein Inner Join aus vier Tabellen verwendet jede Verknüpfung. Warum kann eine Bestell-ID in mehreren Zeilen erscheinen, selbst wenn jeder Primärschlüssel eindeutig ist?
  1. Der Primärschlüssel des Produkts muss doppelt sein.
  2. Jeder Join gibt alle Produkte für jede Bestellung zurück.
  3. Die Bestellung hat mehrere passende Bestellpositionszeilen.
  4. Eindeutige Schlüssel verhindern Eins-zu-viele-Beziehungen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Die Zonen A und B müssen beide erscheinen. A hat eine Buchung, die mit einer tatsächlichen Leistung verknüpft ist; B hat keine Buchungen. Die Abfrage verknüpft Buchungen und Leistungen mit Left Joins und ergänzt dann WHERE service.category = 'Repair'. Die Leistung von A hat die Kategorie Repair. Was bleibt erhalten?
  1. A mit seiner Leistung; B mit NULL
  2. A mit seiner Leistung; B verschwindet
  3. Beide Zonen mit Leistungsfeldern NULL
  4. B mit NULL; A verschwindet
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Zwei Abonnenten heißen beide Lee und haben die IDs 41 und 42. Der erste hat zwei Zahlungen und der zweite eine. Wie viele Zeilen geben SELECT DISTINCT name und SELECT DISTINCT subscriber_id, name nach einem Inner Join mit den Zahlungen zurück?
  1. 2 und 2
  2. 1 und 3
  3. 3 und 2
  4. 1 und 2
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine Nachschlagetabelle enthält Code X zweimal und Code Y einmal. Ein Ereignis verweist auf X und zwei Ereignisse verweisen auf Y. Wie viele Zeilen erzeugt ihr Inner Join?
  1. 4
  2. 3
  3. 5
  4. 6
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 5: Vollständige Berichte unter veränderten Bedingungen prüfen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Tabelle A hat Schlüsselzeilen mit 1, 1, 2. Tabelle B hat Schlüsselzeilen mit 1, 1, 1, 3. Wie viele Zeilen gibt ein Inner Join mit Gleichheitsbedingung zurück?
  1. 3
  2. 7
  3. 6
  4. 12
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Wert von 9,50 wird durch einen Inner Join mit einschließenden BETWEEN-Prüfungen den Bereichen [0.00, 9.00], [10.00, 20.00] und [8.00, 12.00] zugeordnet. Wie ändert sich die Ausgabe für diesen Wert, wenn der dritte Bereich entfernt wird?
  1. Von zwei Zeilen auf eine Zeile
  2. Von einer Zeile auf eine Zeile
  3. Von drei Zeilen auf zwei Zeilen
  4. Von einer Zeile auf null Zeilen
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Liste A enthält die Schlüssel 4, 4, 9; Liste B enthält die Schlüssel 4, 4, 12. Ein Full Join mit Gleichheitsbedingung wählt beide Schlüsselspalten aus. Wie viele Zeilen werden zurückgegeben und wie viele bleiben nach WHERE a.k IS NULL OR b.k IS NULL erhalten?
  1. 4 insgesamt; 2 ohne Partner
  2. 6 insgesamt; 2 ohne Partner
  3. 6 insgesamt; 4 ohne Partner
  4. 9 insgesamt; 2 ohne Partner
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Die Kunden P und Q haben jeweils eine alte Bestellung und keine neueren Bestellungen; R hat keine Bestellungen. Auf einen LEFT JOIN nur über den Schlüssel folgt WHERE o.date >= '2026-09-01' OR o.order_id IS NULL. Welche Kunden bleiben erhalten?
  1. Nur R
  2. P, Q und R
  3. Nur P und Q
  4. Keine Kunden
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein CROSS JOIN kombiniert 2 Modi, 5 Regionen und 4 Monate. Wie viele Kombinationen erzeugt er?
  1. 11
  2. 20
  3. 40
  4. 10
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Die Mitglieder sind 7, 8 und 9; die Vereine sind 50 und 60. Die Mitgliedschaftspaare sind (7,50), (7,60) und (8,50). Eine Abfrage verknüpft members mit memberships und danach clubs jeweils über Left Joins. Wie viele Zeilen gibt es insgesamt und welchen Vereinswert hat Mitglied 9?
  1. 3 Zeilen; NULL
  2. 4 Zeilen; NULL
  3. 4 Zeilen; 60
  4. 6 Zeilen; NULL
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Die Gruppen G und H müssen beide erscheinen. G hat eine Anmeldung, die mit einem vorhandenen Kurs verknüpft ist; H hat keine. Vergleiche groups LEFT JOIN signups JOIN classes mit groups LEFT JOIN (signups JOIN classes) anhand der jeweiligen Schlüssel. Was geschieht mit H?
  1. Nur der gruppierte optionale Pfad erhält H.
  2. Beide Formen erhalten H.
  3. Nur der nicht gruppierte Pfad erhält H.
  4. Keine der Formen erhält H.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Kunde hat die Rechnungen 501 über 18,00 und 502 über 27,00. Rechnung 501 hat 3 Positionen; Rechnung 502 hat 2. Der Bericht braucht den gesamten Rechnungswert und die Anzahl der Rechnungen. Welches Ergebnis sollte er ausweisen?
  1. 108,00 und 5
  2. 45,00 und 5
  3. 108,00 und 2
  4. 45,00 und 2
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine Tabelle speichert eine Kennung in einer TEXT-Spalte als „0064“; eine andere speichert 64 in einer INTEGER-Spalte. Was solltest du prüfen, bevor du dich bei verschiedenen Datenbanken auf ihren Join mit Gleichheitsbedingung verlässt?
  1. Nur, ob beide Tabellen gleich viele Zeilen haben
  2. Nur, ob beide Spalten denselben Namen haben
  3. Die Schlüsseltypen, Formate und das Umwandlungsverhalten
  4. Ob DISTINCT alle Zeilen ohne Partner entfernen kann
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Eine Elternzeile hat 2 Rechnungen und 4 Fälle, die unabhängig voneinander über die Eltern-ID verknüpft sind. Ein Inner Join mit beiden Kindtabellen gruppiert nach Elternzeile. Was ergeben COUNT(*), COUNT(DISTINCT bill_id) und COUNT(DISTINCT case_id)?
  1. 6, 2 und 4
  2. 8, 2 und 4
  3. 8, 8 und 8
  4. 4, 2 und 4
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe

Schlüsselbegriffe

58 Schlüsselbegriffe, jeweils mit Definition

A

Abgleich
Ein Abgleich vergleicht Datensätze, die übereinstimmen sollten, ordnet passende Schlüssel einander zu und macht fehlende Datensätze oder abweichende Werte sichtbar.
Ein Full Join kann den Lagerbestand neben eine Inventur stellen und dabei Artikelnummern erhalten, die in einer der beiden Listen fehlen.
abhängige Verknüpfung
Eine abhängige Verknüpfung verbindet eine spätere Tabelle über eine Spalte einer zuvor verknüpften Tabelle, sodass fehlende frühere Partner sie beeinflussen.
Ein Kurs-Join hängt von der Kurs-ID der Einschreibung ab; ein Studierender ohne Einschreibung hat eine Kurs-ID NULL, die diese Gleichheitsbedingung nicht erfüllen kann.
abweichendes Schlüsselformat
Ein abweichendes Schlüsselformat liegt vor, wenn verknüpfte Kennungen unterschiedliche Typen oder Darstellungen verwenden, sodass das Vergleichsverhalten von der Datenbank abhängt.
Der Text „0042“ und die Zahl 42 können in SQLite durch Umwandlung zusammenpassen, brauchen aber über Systeme hinweg eine einheitliche Behandlung.
Aggregationsebene
Eine Aggregationsebene ist die Art von Datensatz, die eine Zählung oder Summe erfassen soll, etwa Kunden, Bestellungen oder Bestellpositionen.
Zähle unterschiedliche Bestell-IDs, wenn die verknüpften Zeilen Positionen darstellen, der Bericht aber nach der Anzahl der Bestellungen fragt.
AND in einer Join-Bedingung
AND in einer Join-Bedingung verlangt, dass alle Teilprüfungen wahr sind, bevor das betrachtete Paar als Treffer gilt.
Der Abgleich von Geschäft und Monat verhindert, dass die Aprilzeile eines Geschäfts mit dessen Märzzahlen verknüpft wird.
Anti-Join
Ein Anti-Join gibt Zeilen ohne passenden Partner zurück. Diese lassen sich mit einem Left Join und einer anschließenden Prüfung auf einen fehlenden rechten Schlüssel finden.
Verknüpfe Produkte mit Bestellpositionen über einen Left Join und prüfe den fehlenden Positionsschlüssel, um unverkaufte Produkte wie einen Tacker zu finden.

B

Berichtsraster
Ein Berichtsraster ist eine vollständige Liste benötigter Kombinationen, die mit einem Cross Join erstellt und mit einem Left Join gefüllt werden kann.
Die Kombination von Geschäften und Monaten macht fehlende Verkaufsmonate sichtbar, wenn tatsächliche Verkäufe hinzugefügt werden.
Bestellposition
Eine Bestellposition ist ein Datensatz für ein Produkt innerhalb einer Bestellung, der gewöhnlich Bestell- und Produktschlüssel verknüpft und die Menge speichert.
Bestellung 101 hat getrennte Positionen für Mug und Pen, sodass sich ihre Kunden- und Bestellwerte im Detailbericht wiederholen.
Beziehungsattribut
Ein Beziehungsattribut ist ein Fakt über eine bestimmte Verknüpfung zwischen Datensätzen und gehört daher in die Zeile, die diese Verknüpfung darstellt.
Die Menge wird in einer Bestellpositionszeile gespeichert, weil dasselbe Produkt in verschiedenen Bestellungen in unterschiedlichen Mengen gekauft werden kann.

C

COALESCE
COALESCE gibt sein erstes Argument zurück, das nicht NULL ist. Damit kann ein Ergebnis einen Ersatzwert oder einen auf einer der beiden Seiten verfügbaren Schlüssel anzeigen.
COALESCE(o.total, 0) zeigt null an, wenn die verknüpfte Bestellsumme NULL ist. Wähle die Spaltenbezeichnung daher sorgfältig.
COUNT(*)
COUNT(*) zählt Ergebniszeilen, einschließlich des mit NULL aufgefüllten Platzhalters eines Outer Joins für eine Elternzeile ohne passende Kindzeile.
Nach einem Left Join von der Kundenseite trägt ein Kunde ohne Bestellung eine Zeile zu COUNT(*) bei.
COUNT(DISTINCT Schlüssel)
COUNT(DISTINCT Schlüssel) zählt jeden unterschiedlichen Schlüssel, der nicht NULL ist, einmal und ignoriert Wiederholungen durch den Abgleich mit mehreren Detailzeilen.
Enthalten die drei Positionszeilen eines Kunden nur zwei Bestell-IDs, ergibt das Zählen unterschiedlicher Bestell-IDs zwei.
COUNT(Spalte)
COUNT(Spalte) zählt Werte einer ausgewählten Spalte, die nicht NULL sind, und kann so nach einem Left Join tatsächliche optionale Partner zählen.
Ein Kunde ohne Bestellung hat einen verknüpften Bestellschlüssel NULL, der in der Gruppe dieses Kunden null zu COUNT(o.order_id) beiträgt.
Cross Join
Ein Cross Join gibt ohne Abgleichsbedingung jedes Paar von Eingabezeilen zurück. Die Zeilenanzahl ist das Produkt der Zeilenanzahlen beider Eingaben.
Drei Hemdgrößen mit zwei Farben ergeben sechs mögliche Größen-Farben-Zeilen für das Geschäft.

D

DISTINCT
DISTINCT entfernt Zeilen, die in allen ausgewählten Werten identisch sind; es korrigiert keine falsche Beziehung und entfernt nicht von selbst doppelte Entitäten.
Die Auswahl unterschiedlicher Kunden-IDs und Namen hält verschiedene Personen getrennt, auch wenn sie denselben Namen haben.
doppelter Nachschlageschlüssel
Ein doppelter Nachschlageschlüssel ist ein wiederholter Wert auf einer Seite, auf der Eindeutigkeit erwartet wird, und gibt passenden Eingabezeilen zusätzliche Partner.
Erscheint ein Ländercode zweimal, erzeugen Kunden mit diesem Code jeweils zwei verknüpfte Nachschlagetreffer.

E

Eins-zu-eins-Beziehung
Eine Eins-zu-eins-Beziehung erlaubt höchstens einen Partner pro Zeile auf jeder Seite, gewöhnlich durch einen Fremdschlüssel, der ebenfalls eindeutig ist.
Kann jeder Mitarbeiter höchstens einen Ausweis haben, setzt ein eindeutiger Mitarbeiterverweis in badges diese Verknüpfung durch.
Eins-zu-viele-Beziehung
Eine Eins-zu-viele-Beziehung erlaubt einer Elternzeile mehrere Kindzeilen; der Fremdschlüssel wird auf der Kindseite gespeichert.
Hat ein Kunde zwei Bestellungen, verweisen beide Bestellzeilen auf dessen ID, ohne die Adresse zu wiederholen.
Einschränkung der Join-Partner
Eine Einschränkung der Join-Partner begrenzt in ON, welche möglichen Partner als Treffer gelten, während ein Outer Join weiterhin seine erforderlichen Eingabezeilen erhält.
Ein Stichtag für das Bestelldatum in ON erhält jeden Kunden, fügt aber nur Bestellungen hinzu, die den Stichtag erfüllen.
Einschreibung
Eine Einschreibung verbindet einen Studierenden mit einem Kurs und kann durch eine Zeile in einer Zwischentabelle mit diesen beiden identifizierenden Schlüsseln dargestellt werden.
Mias Kurse Algebra und Biology benötigen getrennte Einschreibungszeilen; Omar hat keine Einschreibungszeile.
Equi-Join
Ein Equi-Join gleicht Zeilen mit Gleichheitsvergleichen ab, oft zwischen einem Fremdschlüssel und dem Primärschlüssel oder eindeutigen Schlüssel, auf den er verweist.
Die Kunden-ID 1 in einer Bestellung entspricht der Kunden-ID 1 in der passenden Kundenzeile, sodass dieses Paar den Equi-Join erfüllt.
erhaltene Seite
Die erhaltene Seite eines Outer Joins ist die Eingabe, deren Zeilen ohne Partner zurückgegeben werden müssen, bevor spätere Joins oder Filter wirken.
Customers ist in customers c LEFT JOIN orders o unabhängig von der Anzahl der Bestellungen die erhaltene Seite.

F

Fan-out
Fan-out wiederholt eine Elternzeile für jede passende Kindzeile. Das ist für Detaillisten nützlich, kann aber Summen auf Elternebene vervielfachen.
Hat Bestellung 101 mit einer Summe von 22,00 zwei Positionen, erscheint sie nach deren Join zweimal, sodass diese Summe zweimal addiert würde.
Filter nach dem Join
Ein Filter nach dem Join wird in WHERE auf die vom Join gebildeten Zeilen angewendet und kann sowohl passende als auch mit NULL aufgefüllte Outer-Join-Zeilen entfernen.
Ein rechtsseitiger Datumsvergleich in WHERE entfernt einen Kunden ohne Bestellungen, weil das verknüpfte Bestelldatum dieses Kunden NULL ist.
Fremdschlüssel
Ein Fremdschlüssel ist eine Spalte oder eine Gruppe von Spalten, die auf einen Primärschlüssel oder einen eindeutigen Schlüssel in derselben oder einer anderen Tabelle verweist.
Mehrere Bestellungen können die Kunden-ID 1 enthalten und so jede dieser Bestellungen mit der einzigen Kundenzeile mit dieser ID verbinden.
Full Outer Join
Ein Full Outer Join gibt passende Paare zurück und erhält Zeilen ohne Partner aus beiden Eingaben, mit NULL-Werten für jeden fehlenden Partner.
Ein Full Join von Kunden und Bestellungen erhält neben den passenden Bestellungen auch Kunden ohne Bestellungen und Gastbestellungen ohne Kunden.

G

geklammerter Join
Ein geklammerter Join gruppiert verknüpfte Eingaben ausdrücklich, sodass eine durch Inner Joins verbundene Gruppe als eine optionale Seite eines Outer Joins dienen kann.
Mit Kursen verknüpfte Einschreibungen können eine Gruppe bilden, die anschließend über einen Left Join mit allen Studierenden verknüpft wird, auch mit denen ohne Einschreibung.
gemischte Join-Kette
Eine gemischte Join-Kette kombiniert Inner und Outer Joins. Dabei muss bei jedem Schritt geprüft werden, welche früheren Zeilen er entfernen kann.
Ein Left Join mit Bestellungen, gefolgt von einem Inner Join mit Bestellpositionen, entfernt Kunden, deren Bestellschlüssel NULL ist.

H

Hierarchie
Eine Hierarchie ist eine Struktur aus Eltern-Kind-Verknüpfungen, etwa aus Berichtswegen von Mitarbeitern, der ein Self Join jeweils eine Ebene folgen kann.
Jamal berichtet an Hassan, der an Grace berichtet; drei Tabellenrollen können diese Kette aus zwei Verknüpfungen zeigen.

I

Inner Join
Ein Inner Join gibt jedes Paar zurück, das seine Join-Bedingung erfüllt, und schließt Zeilen aus beiden Eingaben aus, die keinen Partner finden.
Hat Ana zwei Bestellungen und Ben eine, gibt ein Inner Join von Kunden und Bestellungen diese drei Bestellungen zurück und lässt eine Gastbestellung aus.
IS-NULL-Prüfung
Eine IS-NULL-Prüfung ist wahr, wenn ein Wert NULL ist. Wird sie auf einen geeigneten Schlüssel angewendet, kann sie nach einem Outer Join fehlende Partner auswählen.
Die Prüfung o.order_id IS NULL erhält Kunden ohne Bestellungen; o.order_id = NULL erhält keine Zeilen.

J

Join
Ein Join kombiniert Eingabezeilen nach einer Abgleichsregel zu Ergebniszeilen und kann dabei Zeilen ohne Partner mit NULL-Werten erhalten.
Der Name eines Kunden und die Summe einer Bestellung können zusammen erscheinen, nachdem ihre Zeilen über die Kunden-ID verknüpft wurden.
Join-Bedingung
Eine Join-Bedingung ist der Ausdruck, der entscheidet, ob ein Paar zusammenpasst; nur ein wahres Ergebnis gilt als Treffer.
o.customer_id = c.customer_id paart Bestellung 101, die Kunden-ID 1 enthält, mit der Kundenzeile, deren ID ebenfalls 1 ist.
Join-Kette
Eine Join-Kette fügt in einer Abfrage mehrere Tabellen hinzu, wobei jeder neue Join auf die von den vorhergehenden Joins gebildeten Zeilen wirkt.
Bildet ein Join von Kunden und Bestellungen drei Paare und haben diese Bestellungen fünf Positionen, erweitert der Join mit order_items sie zu fünf Detailzeilen.
Join-Pfad
Ein Join-Pfad ist eine Folge sinnvoller Verknüpfungen zwischen den für eine Abfrage benötigten Tabellen, mit einer Bedingung für jede Verknüpfung.
Der Einkaufsbericht folgt customers zu orders, dann zu order_items und schließlich zu products, um Produktnamen zu erreichen.

K

kartesisches Produkt
Ein kartesisches Produkt ist die vollständige Sammlung von Kombinationen, die entstehen, wenn aus jeder Eingabetabelle eine Zeile gewählt wird.
Stellt man jeden Kunden neben jede Bestellung, entstehen alle möglichen Kunden-Bestellungs-Paare, einschließlich nicht zusammengehöriger Paarungen.
Komma-Join
Ein Komma-Join nennt Tabellen durch Kommas getrennt in FROM und drückt ihre Abgleichsbedingung in der WHERE-Klausel der Abfrage aus.
Entfernt man die Kundenschlüsselprüfung aus einem Komma-Join von vier Kunden und vier Bestellungen, wird jeder Kunde mit jeder Bestellung gepaart.

L

Left Outer Join
Ein Left Outer Join erhält jede linke Zeile und gibt jedes passende Paar oder eine rechtsseitig mit NULL aufgefüllte Zeile zurück, wenn kein Partner passt.
Ein Kunde, der nie bestellt hat, erscheint weiterhin in einem Kundenbericht mit Left Join, mit NULL in den Bestellspalten.

M

mehrdeutige Spalte
Eine mehrdeutige Spalte ist ein nicht qualifizierter Verweis, der eine Spalte in mehr als einer Eingabe bezeichnen könnte, sodass seine Herkunft unklar bleibt.
Bei JOIN ... ON schlägt die Auswahl von customer_id ohne Qualifizierung fehl, wenn sowohl customers als auch orders die Spalte liefern.
mit NULL aufgefüllte Zeile
Eine mit NULL aufgefüllte Zeile ist ein Outer-Join-Ergebnis, das eine Eingabezeile ohne Partner erhält und für die Spalten des fehlenden Partners NULL liefert.
Eine Bestellnummer NULL für einen Kunden in einem Left-Join-Ergebnis kennzeichnet einen fehlenden Bestellpartner; sie ist keine gespeicherte Bestellung.

N

Natural Join
Ein Natural Join gleicht automatisch jeden Spaltennamen ab, den die Eingaben gemeinsam haben. Änderungen an gemeinsamen Namen können daher sein Ergebnis ändern.
Wird orders eine Lieferortspalte hinzugefügt, vergleicht ein Natural Join neben den Kunden-IDs auch die Orte.
Non-Equi-Join
Ein Non-Equi-Join gleicht Zeilen mit einem anderen Vergleich als Gleichheit ab, etwa wenn ein Preis zwischen der unteren und oberen Grenze eines Bereichs liegt.
Eine Tasse zum Preis von 8,00 fällt in den Preisbereich Standard und wird mit dessen Bezeichnung verknüpft.

O

ON-Klausel
Eine ON-Klausel gibt den Abgleichsausdruck für einen Join an und kann mehrere Vergleiche verbinden, die für ein Paar gelten müssen.
Eine Bedingung, die Versandpositionen Bestellpositionen zuordnet, verwendet sowohl die Bestell-ID als auch die Produkt-ID, um den richtigen Partner zu identifizieren.
optionale Seite
Die optionale Seite eines Left Joins ist die rechte Eingabe, deren Spalten mit NULL aufgefüllt werden, wenn eine erhaltene Zeile keinen Partner hat.
Orders ist in einem Bericht über alle Kunden optional, sodass eine fehlende Bestellung den Kunden nicht entfernen darf.

P

Primärschlüssel
Ein Primärschlüssel ist eine Spalte oder eine Gruppe von Spalten, deren Wert eine Zeile eindeutig identifiziert und kein NULL enthalten darf.
In einer Kundentabelle unterscheidet customer_id den Datensatz eines Kunden von allen anderen Kundendatensätzen.

Q

qualifizierter Spaltenname
Ein qualifizierter Spaltenname enthält einen Tabellennamen oder Alias vor der Spalte und gibt so an, welche Eingabe den Wert liefert.
c.customer_id wählt den Schlüssel der Kundenseite aus, wenn beide verknüpften Tabellen customer_id enthalten.

R

Right Outer Join
Ein Right Outer Join erhält alle rechten Zeilen und ergänzt linksseitig NULL-Werte, wenn eine rechte Zeile keinen Partner hat, der die Bedingung erfüllt.
Steht orders rechts, bleibt eine Gastbestellung 104 mit Kundenverweis NULL erhalten, obwohl keine Kundenzeile zu ihr passen kann.

S

Selbstpaarung
Eine Selbstpaarung verknüpft eine Zeile mit sich selbst, wenn eine Self-Join-Bedingung beiden Aliasen erlaubt, auf denselben identifizierenden Schlüssel zu verweisen.
Eine Mitarbeiterzeile wird mit sich selbst gepaart, wenn eine Self-Join-Bedingung nur prüft, ob die Vorgesetzten-IDs beider Aliase gleich sind.
Self Join
Ein Self Join verknüpft eine Tabelle unter getrennten Aliasen mit sich selbst, sodass ihre Zeilen unterschiedliche Rollen spielen oder miteinander verglichen werden können.
Der Mitarbeiteralias liefert manager_id und der Vorgesetztenalias die passende emp_id.

T

Tabellenalias
Ein Tabellenalias ist ein kurzer Name für einen Tabellenverweis, damit dessen Rolle und Spaltenverweise innerhalb einer Abfrage klar bleiben.
In FROM customers c ermöglicht der Alias c der Abfrage, den Kundennamen als c.name anzusprechen.

U

unbeabsichtigter Cross Join
Ein unbeabsichtigter Cross Join kombiniert jedes Zeilenpaar, weil eine benötigte Bedingung fehlt oder immer wahr ist, und erzeugt nicht zusammengehörige Treffer.
Eine vergessene Bedingung lässt einen Kunden neben Bestellungen anderer Kunden und seinen eigenen erscheinen und vergrößert das Ergebnis.
unbekanntes Vergleichsergebnis
Ein unbekanntes Vergleichsergebnis entsteht bei gewöhnlicher Gleichheit mit NULL und zählt weder beim Abgleich noch beim Filtern mit WHERE als wahr.
Gastbestellung 104 hat einen Kundenverweis NULL und kann daher durch Gleichheit nicht einmal zu einem anderen NULL passen.
ungeordnetes Paar
Ein ungeordnetes Paar behandelt zwei Elemente in jeder Reihenfolge als dieselbe Paarung; ein Vergleich unterschiedlicher IDs mit < erhält es einmal.
Das Kollegenpaar Hassan–Iris erscheint einmal, wenn die Bedingung verlangt, dass die erste Mitarbeiter-ID kleiner ist.
USING-Klausel
Eine USING-Klausel listet gleichnamige Spalten für einen Gleichheitsvergleich auf und zeigt jede aufgeführte gemeinsame Spalte in SELECT * einmal an.
USING (customer_id) drückt den Abgleich der Kundenschlüssel aus, ohne beide Spaltenverweise auszuschreiben.

V

Viele-zu-viele-Beziehung
Eine Viele-zu-viele-Beziehung erlaubt Zeilen auf beiden Seiten mehrere Partner und wird mit einer Tabelle aus verknüpfenden Paaren dargestellt.
Wenn ein Studierender zwei Kurse belegt und ein Kurs zwei Studierende umfasst, erfasst eine enrollments-Tabelle jedes Paar aus Studierendem und Kurs.
Vorhersage der Zeilenanzahl
Eine Vorhersage der Zeilenanzahl schätzt das Ergebnis eines Joins anhand der Abgleichsbeziehungen und der Zeilen ohne Partner, die sein Join-Typ erhält.
Drei passende Bestellungen und zwei Kunden ohne Partner lassen fünf Zeilen für den Left Join von der Kundenseite erwarten.

Z

zusammengesetzter Schlüssel
Ein zusammengesetzter Schlüssel identifiziert einen Datensatz anhand mehrerer Spalten zusammen; der Abgleich eines Verweises mit ihm erfordert jeden Schlüsselbestandteil.
Das Paar aus Studierendem und Kurs verhindert doppelte Einschreibungen, obwohl weder die Studierenden-ID noch die Kurs-ID allein eindeutig ist.
Zwischentabelle
Eine Zwischentabelle erfasst eine Zeile pro Beziehungspaar und enthält je einen Fremdschlüssel zu jedem Endpunkt einer Viele-zu-viele-Verknüpfung.
Jede Einschreibungszeile verbindet einen Studierenden mit einem Kurs, sodass sich sowohl Studierende als auch Kurse wiederholen können.

Über diese Einheit

Von StudeliFehler melden

Erstelle deine eigenen Lernmaterialien

Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.

Jetzt starten