Verified Commit a691b4db authored by Benedikt's avatar Benedikt
Browse files

update joins

parent 92d5bc81
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
---
title: JOINS
description: blabla
permalink: /datenbanken/sql/data-query-language/joins/
---

# Datensätze kombinieren

Joins werden in SQL verwendet, um Datensätze aus **mehreren** Tabellen zu kombinieren.

Da in einer normalisierten Datenbank die Daten in verschiedenen Tabellen abgelegt sind,
um Redundanzen zu vermeiden (und die Gefahr für Anomalien und Inkonsistenzen zu verringern),
sind Joins ein wichtiges Werkzeug im SQL Werkzeugkasten, um die Daten wieder zusammenzuführen.

## Arten von Joins

Es gibt verschiedene Arten von Joins:

- [**INNER JOIN**](inner/) - Gibt nur Datensätze zurück, zu denen es in beiden Tabellen eine Übereinstimmung gibt

- [**LEFT OUTER JOIN**](outer/) - Gibt **alle** Zeilen aus der linken Tabelle zurück und passende Zeilen aus der rechten – wenn keine passen, wird mit NULL aufgefüllt.

- [**RIGHT OUTER JOIN**](outer/) - Umgekehrt wie LEFT OUTER JOIN.

- **FULL OUTER JOIN** - Eine Kombination aus LEFT und RIGHT OUTER JOIN. Gibt alle Zeilen aus beiden Tabellen zurück – wo es keine Übereinstimmung gibt, wird NULL ergänzt.

- **CROSS JOIN** - Kombiniert jede Zeile der ersten Tabelle mit jeder Zeile der zweiten (kartesisches Produkt).

In MariaDB gibt es keinen FULL OUTER JOIN, man kann ihn jedoch mit anderen Werkzeugen nachbauen.
+16 −27
Original line number Diff line number Diff line
---
title: JOIN
title: INNER JOIN
description: blabla
kapitel: [3]
kapitel: [1]
---

# Datensätze kombinieren

Joins werden in SQL verwendet, um Datensätze aus mehreren Tabellen zu kombinieren.
Da in einer normalisierten Datenbank die Daten in verschiedenen Tabellen abgelegt sind,
um Redundanzen zu vermeiden (und die Gefahr für Anomalien und Inkonsistenzen zu verringern),
sind Joins ein wichtiges Werkzeug im SQL Werkzeugkasten, um die Daten wieder zusammenzuführen.

## Arten von Joins

Es gibt verschiedene Arten von Joins:

- **INNER JOIN** - Gibt nur Datensätze zurück, zu denen es in beiden Tabellen eine Übereinstimmung gibt

- **LEFT OUTER JOIN** - Gibt **alle** Zeilen aus der linken Tabelle zurück und passende Zeilen aus der rechten – wenn keine passen, wird mit NULL aufgefüllt.

- **RIGHT OUTER JOIN** - Umgekehrt wie LEFT OUTER JOIN.

- **FULL OUTER JOIN** - Eine Kombination aus LEFT und RIGHT OUTER JOIN. Gibt alle Zeilen aus beiden Tabellen zurück – wo es keine Übereinstimmung gibt, wird NULL ergänzt.

- **CROSS JOIN** - Kombiniert jede Zeile der ersten Tabelle mit jeder Zeile der zweiten (kartesisches Produkt).

In MariaDB gibt es keinen FULL OUTER JOIN, man kann ihn jedoch mit anderen Werkzeugen nachbauen.

## INNER JOIN
# INNER JOIN

{% svg "join/inner_venn" %}

Der INNER JOIN kombiniert Datensätze, bei denen es in beiden Tabellen eine Überstimmung gibt, basierend auf einer Bedingung.
Der INNER JOIN kombiniert Datensätze, bei denen es in beiden Tabellen eine Überstimmung gibt, basierend auf einer Join-Bedingung.

## Syntax von INNER JOIN

@@ -91,6 +68,18 @@ sieht das Ergebnis viel besser aus:

{% svg "join/inner_4" %}

<br>

## Ausgefilterte Zeilen

Die rot markierten Zeilen sind nicht in der Ergebnistabelle vorhanden,
das liegt daran, dass diese Zeilen keinen "Join-Partner" in der jeweils anderen Tabelle gefunden haben. 

{% svg "join/left_1" %}

Warum manchmal gerade diese Zeilen so interessant sind und wie man sie per Query ausliest, erfahren Sie auf der [nächsten Seite](../outer/).


## Fazit

Wie wir gesehen haben, ist es ohne viel Aufwand möglich, die ausgelagerten Daten
+6 −0
Original line number Diff line number Diff line
{
  "tags": ["joins"],
  "permalink": "/datenbanken/sql/data-query-language/joins/{{ page.fileSlug }}/",
  "pageTitleParts": ["JOINS"],
  "kapitel": [3]
}
 No newline at end of file
+106 −0
Original line number Diff line number Diff line
---
title: OUTER JOIN
description: blabla
kapitel: [2]
---

# OUTER JOIN

Der LEFT OUTER JOIN
{% svg "join/left_venn" %}

<br>

Der RIGHT OUTER JOIN
{% svg "join/right_venn" %}

Mit den OUTER JOINS bekommt man zunächst alle Zeilen die auch ein INNER JOIN liefern würde,
erhält dann aber zusätzlich **ALLE** Zeilen aus der linken oder rechten Tabelle.

Mit linker Tabelle ist die erstgenannte Tabelle gemeint:
```sql
SELECT ... FROM tabelle_links
...
```

Mit rechter Tabelle ist die zweitgenannte Tabelle gemeint:
```sql
SELECT ... FROM tabelle_links
LEFT | INNER | RIGHT JOIN tabelle_rechts
...
```


## Syntax von LEFT OUTER JOIN

```sql
SELECT ... FROM tabelle_l
LEFT OUTER JOIN tabelle_r ON <Bedingung>;
```

Das Wort `OUTER` ist optional und kann auch weggelassen werden:

```sql
SELECT ... FROM tabelle_l
LEFT JOIN tabelle_r ON <Bedingung>;
```

<br>

## Wofür braucht man das?

Wir haben beim INNER JOIN gesehen, dass die rot markierten Datensätze
nicht in der Ergebnistabelle auftauchen, sie hatten keinen JOIN-Partner in der anderen Tabelle:

```sql
SELECT * 
FROM Mitarbeiter m
    INNER JOIN Abteilung a
    ON m.abteilung = a.id;
```

{% svg "join/left_1" %}

Manchmal will man an genau diese Datensätze ran, da alleine die Existenz (oder nicht-Existenz) dieser Datensätze schon Informationen erhält.

Mit einem LEFT [OUTER] JOIN kann man rausfinden, welche Datensätze aus der linken Tabelle
**kein** Match in der rechten Tabelle haben. Damit kann man z.B. Fragen beantworten wie:

- Welche Kunden haben noch keine Bestellung aufgegeben?

- Welcher Film wurde noch nie ausgeliehen?

- Welche Mitarbeiter betreuen keine Kunden?

## Anwenden

Wir wollen jetzt rausfinden, welche Mitarbeiter noch keiner Abteilung zugewiesen sind.
Dafür nehmen wir den INNER JOIN Query und ersetzen **INNER** durch **LEFT OUTER**:

```sql
SELECT * 
FROM Mitarbeiter m
    LEFT OUTER JOIN Abteilung a
    ON m.abteilung = a.id;
```

{% svg "join/left_2" %}

Wir bekommen die gleichen Ergebniszeilen wie mit dem INNER JOIN,
bekommen zusätzlich aber noch die restlichen Zeilen aus Tabelle 1. 
Dort wo die Daten aus Tabelle 2 kommen würden, wird mit NULL aufgefüllt.

Diese NULL - Werte kann man sich zunutze machen. Wir filtern jetzt nach den Zeilen,
in denen die Spalte **Abteilung.id** den Wert **NULL** hat:

```sql
SELECT * 
FROM Mitarbeiter
    LEFT OUTER JOIN Abteilung
    ON Mitarbeiter.abteilung = Abteilung.id
WHERE Abteilung.id IS NULL;
```

Beachten Sie, dass zum Testen auf NULL `IS NULL` oder `IS NOT NULL`
verwendet werden muss, anstatt einen Vergleichoperator zu verwenden (Abteilung.id = NULL).
[https://www.w3schools.com/sql/sql_null_values.asp](https://www.w3schools.com/sql/sql_null_values.asp)