DQL: Unterschied zwischen den Versionen

Aus FLBK-Wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
{{Seitenüberschrift|Data Query Language (DQL)}}
== Einführung ==
== Einführung ==
Die '''Data Query Language''' (kurz '''DQL''') der [[SQL|Structured Query Language (SQL)]] ermöglicht es, mittels Abfragen Informationen aus unterschiedlichen Tabellen zusammenzutragen. Das Ergebnis einer Abfrage ist eine [[Relation]] und kann oft auch wie eine Tabelle angezeigt, bearbeitet und weiterverwendet werden. Abfragen basieren auf den Operationen der '''relationalen Algebra'''.
Die '''Data Query Language''' (kurz '''DQL''') der [[SQL|Structured Query Language (SQL)]] ermöglicht es, mittels Abfragen Informationen aus unterschiedlichen Tabellen zusammenzutragen. Das Ergebnis einer Abfrage ist eine [[Relation]] und kann oft auch wie eine Tabelle angezeigt, bearbeitet und weiterverwendet werden. Abfragen basieren auf den Operationen der '''relationalen Algebra'''.
Zeile 15: Zeile 17:
=== Alias (AS) ===
=== Alias (AS) ===
Nach jeder Spalte kann mit dem Schlüsselwort '''AS''' ein neuer Name (Alias) für die Anzeige festgelegt werden.
Nach jeder Spalte kann mit dem Schlüsselwort '''AS''' ein neuer Name (Alias) für die Anzeige festgelegt werden.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT IdMitarbeiter AS Mitarbeiternr, Nachname FROM Mitarbeiter;
SELECT Nachname AS Mitarbeitername, IdMitarbeiter FROM Mitarbeiter;
</syntaxhighlight>
</syntaxhighlight>


Zeile 23: Zeile 24:
Nach dem Schlüsselwort '''FROM''' werden alle Tabellen angegeben, die von der Abfrage betroffen sind. Es muss mindestens eine Tabelle angegeben werden.
Nach dem Schlüsselwort '''FROM''' werden alle Tabellen angegeben, die von der Abfrage betroffen sind. Es muss mindestens eine Tabelle angegeben werden.


'''Einfache Abfrage:'''
'''Einfache Abfrage mit Spaltenauswahl:'''
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT * FROM Mitarbeiter;
SELECT nachname, vorname FROM Mitarbeiter;
</syntaxhighlight>
</syntaxhighlight>


'''Ergebnis:'''
'''Ergebnis:'''
{| class="wikitable"
{| class="wikitable"
! IdMitarbeiter !! Nachname !! Vorname !! FkSalon
! nachname !! vorname
|-
|-
| 1 || Krause || Sabine || 1
| Krause || Sabine
|-
|-
| 2 || Schrotter || Claudia || 1
| Schrotter || Claudia
|-
|-
| 3 || Hermann || Markus || 1
| Hermann || Markus
|-
|-
| 4 || Krause || Christoph || 2
| Krause || Christoph
|-
|-
| 5 || Bitter || Manuel || 2
| Bitter || Manuel
|}
|}


== Filter (WHERE) ==
== Filter (WHERE) ==
Ein Filter schränkt die Ergebnismenge auf Datensätze ein, für die eine Aussage im Sinne der '''booleschen Algebra''' wahr ist. Er wird durch '''WHERE''' eingeleitet.
Ein Filter schränkt die Ergebnismenge auf Datensätze ein, für die eine Aussage im Sinne der '''booleschen Algebra''' wahr ist. Er wird durch '''WHERE''' eingeleitet. Neben den Operatoren `<>` und `=` kann auch '''BETWEEN''' eingesetzt werden, um Ober- und Untergrenze eines Filters gleichzeitig anzugeben.
 
* '''Operatoren:''' `<>`, `=`, `AND`, `OR`, `NOT`.
* '''BETWEEN:''' Gibt Ober- und Untergrenze eines Filters gleichzeitig an.


'''Beispiel komplexer Filter:'''
'''Beispiel komplexer Filter:'''
Zeile 65: Zeile 63:


=== IS NULL ===
=== IS NULL ===
SQL nutzt '''NULL-Werte''' für fehlende Daten. Die Prüfung erfolgt mit `IS NULL` oder `IS NOT NULL`.
SQL nutzt '''NULL-Werte''' für fehlende Informationen. Die Prüfung erfolgt mit `IS NULL` oder `IS NOT NULL`. Dies ist besonders bei äußeren Verbünden (Outer Joins) wichtig.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT * FROM Termin WHERE Datum IS NOT NULL;
SELECT * FROM Termin WHERE Datum IS NOT NULL;
Zeile 82: Zeile 80:


=== Top-N-Zeilen (LIMIT) ===
=== Top-N-Zeilen (LIMIT) ===
Bei MySQL und PostgreSQL wird die Ergebnismenge durch '''LIMIT''' beschränkt, um z. B. nur die "besten" oder aktuellsten Einträge zu erhalten.
Bei MySQL und PostgreSQL wird die Ergebnismenge durch '''LIMIT''' beschränkt, um z. B. nur die aktuellsten Einträge zu erhalten.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT * FROM Warenkorbposition ORDER BY Datum DESC LIMIT 10;
SELECT * FROM Warenkorbposition ORDER BY Datum DESC LIMIT 10;
Zeile 88: Zeile 86:


== Tabellen verknüpfen (JOINs) ==
== Tabellen verknüpfen (JOINs) ==
Werden Informationen aus unterschiedlichen Tabellen benötigt, müssen diese verbunden werden.
Werden Informationen unterschiedlicher Tabellen zusammengefügt, müssen diese über Schlüsselfelder verbunden werden.


=== Innerer natürlicher Verbund (INNER JOIN) ===
=== Innerer natürlicher Verbund (INNER JOIN) ===
Zeile 106: Zeile 104:


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT Salon.Name AS Salonname, Mitarbeiter.Nachname  
SELECT Salon.IdSalon, Salon.Name AS Salonname, Mitarbeiter.Nachname  
FROM Salon INNER JOIN Mitarbeiter ON Salon.IdSalon = Mitarbeiter.FKSalon;
FROM Salon  
INNER JOIN Mitarbeiter ON Salon.IdSalon = Mitarbeiter.FKSalon;
</syntaxhighlight>
</syntaxhighlight>
'''Ergebnis:''' (Salon 3 "Kaiserschnitt" erscheint nicht, da ihm kein Mitarbeiter zugeordnet ist)
{| class="wikitable"
! IdSalon !! Salonname !! Nachname
|-
| 1 || Friedrich List Frisuren || Krause
|-
| 1 || Friedrich List Frisuren || Schrotter
|-
| 1 || Friedrich List Frisuren || Hermann
|-
| 2 || Hammer Haare || Krause
|-
| 2 || Hammer Haare || Bitter
|}


=== Linker äußerer Verbund (LEFT JOIN) ===
=== Linker äußerer Verbund (LEFT JOIN) ===
Alle Datensätze der linken Tabelle werden angezeigt, die der rechten nur bei Übereinstimmung.
Alle Datensätze der linken Tabelle (Tab. A) werden angezeigt. Die der rechten Tabelle nur bei Übereinstimmung, sonst `NULL`.
<html>
<html>
<svg width="200" height="120" viewBox="0 0 200 120">
<svg width="200" height="120" viewBox="0 0 200 120">
Zeile 120: Zeile 133:
</svg>
</svg>
</html>
</html>
<syntaxhighlight lang="sql">
SELECT Salon.Name AS Salonname, Mitarbeiter.Nachname
FROM Salon
LEFT JOIN Mitarbeiter ON Salon.IdSalon = Mitarbeiter.FKSalon;
</syntaxhighlight>
'''Ergebnis:'''
{| class="wikitable"
! Salonname !! Nachname
|-
| Friedrich List Frisuren || Krause
|-
| Friedrich List Frisuren || Schrotter
|-
| Friedrich List Frisuren || Hermann
|-
| Hammer Haare || Krause
|-
| Hammer Haare || Bitter
|-
| Kaiserschnitt || ''NULL''
|}


=== Rechter äußerer Verbund (RIGHT JOIN) ===
=== Rechter äußerer Verbund (RIGHT JOIN) ===
Alle Einträge der rechten Tabelle werden selektiert, auch ohne Verbindung zur linken.
Alle Einträge der rechten Tabelle (Tab. B) werden selektiert, auch wenn keine Verbindung zur linken besteht.
<html>
<html>
<svg width="200" height="120" viewBox="0 0 200 120">
<svg width="200" height="120" viewBox="0 0 200 120">
Zeile 131: Zeile 166:
</svg>
</svg>
</html>
</html>
<syntaxhighlight lang="sql">
-- Hier: Alle Salons (Rechts) anzeigen, auch wenn keine Mitarbeiter (Links) zugeordnet sind
SELECT Mitarbeiter.Nachname, Salon.Name AS Salonname
FROM Mitarbeiter
RIGHT JOIN Salon ON Mitarbeiter.FKSalon = Salon.IdSalon;
</syntaxhighlight>
'''Ergebnis:'''
{| class="wikitable"
! Nachname !! Salonname
|-
| Krause || Friedrich List Frisuren
|-
| Schrotter || Friedrich List Frisuren
|-
| Hermann || Friedrich List Frisuren
|-
| Krause || Hammer Haare
|-
| Bitter || Hammer Haare
|-
| ''NULL'' || Kaiserschnitt
|}


== Gruppierung und Aggregat-Funktionen ==
== Gruppierung und Aggregat-Funktionen ==
Mit '''GROUP BY''' werden Datensätze aggregiert.
Mit '''GROUP BY''' werden Datensätze aggregiert (z. B. `COUNT`, `SUM`, `AVG`). Möchte man die Datensätze in einer gruppierten Abfrage filtern, muss '''HAVING''' anstatt `WHERE` verwendet werden.
* '''Funktionen:''' `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`.
* '''HAVING:''' Filtert aggregierte Gruppen (ein `WHERE` ist hier nicht möglich).


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT SUM(Rechnungsbetrag) AS Umsatz, Mitarbeiter.Nachname  
SELECT SUM(Termin.Rechnungsbetrag) AS Umsatz, Mitarbeiter.Nachname AS Mitarbeiter
FROM Termin INNER JOIN Mitarbeiter ON Termin.FKMitarbeiter = Mitarbeiter.IdMitarbeiter  
FROM TERMIN
GROUP BY Mitarbeiter.IdMitarbeiter HAVING Umsatz > 100;
INNER JOIN Mitarbeiter ON Termin.FKMitarbeiter = Mitarbeiter.IdMitarbeiter  
GROUP BY Mitarbeiter.IdMitarbeiter  
HAVING Umsatz > 100;
</syntaxhighlight>
</syntaxhighlight>
'''Ergebnis:''' 106 | Schrotter (Da Claudia Schrotter Termine über 29€ und 77€ hatte).
'''Ergebnis:'''
{| class="wikitable"
! Umsatz !! Mitarbeiter
|-
| 106 || Schrotter
|}


== Unterabfragen (Verschachtelt) ==
== Unterabfragen (Verschachtelt) ==
Unterabfragen liefern Informationen, die als Grundlage für die Hauptabfrage dienen. Sie müssen immer in Klammern gesetzt werden.
Unterabfragen werden in Klammern gesetzt und liefern Werte für die Hauptabfrage.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
-- Termine mit unterdurchschnittlichem Umsatz
-- Termine mit unterdurchschnittlichem Umsatz
Zeile 153: Zeile 216:


== UNION ==
== UNION ==
Mit '''UNION''' werden zwei Relationen vereint. Doppelte Werte werden ignoriert. Die Spalten müssen vom gleichen Typ sein.
Mit '''UNION''' werden zwei Relationen vereint. Die Spalten müssen vom gleichen Typ sein.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
SELECT nachname FROM Mitarbeiter UNION SELECT nachname FROM Kunde;
SELECT Mitarbeiter.nachname FROM Mitarbeiter  
UNION  
SELECT Kunde.nachname FROM Kunde;
</syntaxhighlight>
</syntaxhighlight>


== Reihenfolge der Abarbeitung ==
== Reihenfolge der Abarbeitung ==
Das DBMS arbeitet eine DQL-Abfrage logisch von "innen nach außen" in dieser Reihenfolge ab:
Das DBMS arbeitet eine DQL-Abfrage logisch in dieser Reihenfolge ab:
 
# '''FROM''' (inkl. JOINs)
{| class="wikitable"
# '''WHERE'''
! Schritt !! Klausel !! Beschreibung
# '''GROUP BY'''
|-
# '''HAVING'''
| 1 || '''FROM''' || Inklusive JOINs: Datenbasis festlegen.
# '''SELECT'''
|-
# '''ORDER BY'''
| 2 || '''WHERE''' || Filterung der einzelnen Datensätze.
# '''LIMIT'''
|-
| 3 || '''GROUP BY''' || Gruppierung der Daten.
|-
| 4 || '''HAVING''' || Filterung der gebildeten Gruppen.
|-
| 5 || '''SELECT''' || Projektion und Berechnungen (SUM, etc.).
|-
| 6 || '''ORDER BY''' || Sortierung des Ergebnisses.
|-
| 7 || '''LIMIT''' || Auswahl der relevanten Datensatzzahl.
|}


[[Kategorie:Datenbanken]]
[[Kategorie:Datenbanken]]
[[Kategorie:FI_I_SDM]]
[[Kategorie:FI_I_SDM]]
[[Kategorie:FI_I_TP2]]
[[Kategorie:FI_I_TP2]]

Version vom 26. Februar 2026, 14:27 Uhr

Vorlage:Seitenüberschrift

Einführung

Die Data Query Language (kurz DQL) der Structured Query Language (SQL) ermöglicht es, mittels Abfragen Informationen aus unterschiedlichen Tabellen zusammenzutragen. Das Ergebnis einer Abfrage ist eine Relation und kann oft auch wie eine Tabelle angezeigt, bearbeitet und weiterverwendet werden. Abfragen basieren auf den Operationen der relationalen Algebra.

Datenbasis

ERM-Modell zur Datenbasis
Tabellenübersicht

Um die Syntax von SQL-Abfragen nachvollziehen zu können, wird die Datenbasis eines Friseursalons verwendet (siehe Bilder). Die Abfragen beziehen sich auf Tabellen wie `Mitarbeiter`, `Salon`, `Kunde` und `Termin`.

Auswahl (SELECT)

Eine Abfrage beginnt mit der Auswahl anzuzeigender Spalten durch das Schlüsselwort SELECT.

  • Spalten werden durch Komma getrennt.
  • Mit einem Sternchen (`*`) werden alle Spalten ausgewählt.
  • Bei mehreren Tabellen wird die Punkt-Notation verwendet: `Tabellenname.Spaltenname`.

Alias (AS)

Nach jeder Spalte kann mit dem Schlüsselwort AS ein neuer Name (Alias) für die Anzeige festgelegt werden.

SELECT Nachname AS Mitarbeitername, IdMitarbeiter FROM Mitarbeiter;

Datenherkunft (FROM)

Nach dem Schlüsselwort FROM werden alle Tabellen angegeben, die von der Abfrage betroffen sind. Es muss mindestens eine Tabelle angegeben werden.

Einfache Abfrage mit Spaltenauswahl:

SELECT nachname, vorname FROM Mitarbeiter;

Ergebnis:

nachname vorname
Krause Sabine
Schrotter Claudia
Hermann Markus
Krause Christoph
Bitter Manuel

Filter (WHERE)

Ein Filter schränkt die Ergebnismenge auf Datensätze ein, für die eine Aussage im Sinne der booleschen Algebra wahr ist. Er wird durch WHERE eingeleitet. Neben den Operatoren `<>` und `=` kann auch BETWEEN eingesetzt werden, um Ober- und Untergrenze eines Filters gleichzeitig anzugeben.

Beispiel komplexer Filter:

SELECT Vorname, Nachname FROM Mitarbeiter 
WHERE (Nachname = 'Krause' OR Vorname = 'Manuel') AND IdMitarbeiter <> 1;

Ergebnis:

Vorname Nachname
Christoph Krause
Manuel Bitter

IS NULL

SQL nutzt NULL-Werte für fehlende Informationen. Die Prüfung erfolgt mit `IS NULL` oder `IS NOT NULL`. Dies ist besonders bei äußeren Verbünden (Outer Joins) wichtig.

SELECT * FROM Termin WHERE Datum IS NOT NULL;

Sortierung und Begrenzung

ORDER BY

Mit ORDER BY wird die Sortierreihenfolge festgelegt.

  • ASC: aufsteigend (Standard)
  • DESC: absteigend
SELECT Nachname, Vorname FROM Mitarbeiter ORDER BY Nachname ASC;

Top-N-Zeilen (LIMIT)

Bei MySQL und PostgreSQL wird die Ergebnismenge durch LIMIT beschränkt, um z. B. nur die aktuellsten Einträge zu erhalten.

SELECT * FROM Warenkorbposition ORDER BY Datum DESC LIMIT 10;

Tabellen verknüpfen (JOINs)

Werden Informationen unterschiedlicher Tabellen zusammengefügt, müssen diese über Schlüsselfelder verbunden werden.

Innerer natürlicher Verbund (INNER JOIN)

Zeigt nur Datensätze an, für die in beiden Tabellen eine Entsprechung existiert. Tab. A Tab. B

SELECT Salon.IdSalon, Salon.Name AS Salonname, Mitarbeiter.Nachname 
FROM Salon 
INNER JOIN Mitarbeiter ON Salon.IdSalon = Mitarbeiter.FKSalon;

Ergebnis: (Salon 3 "Kaiserschnitt" erscheint nicht, da ihm kein Mitarbeiter zugeordnet ist)

IdSalon Salonname Nachname
1 Friedrich List Frisuren Krause
1 Friedrich List Frisuren Schrotter
1 Friedrich List Frisuren Hermann
2 Hammer Haare Krause
2 Hammer Haare Bitter

Linker äußerer Verbund (LEFT JOIN)

Alle Datensätze der linken Tabelle (Tab. A) werden angezeigt. Die der rechten Tabelle nur bei Übereinstimmung, sonst `NULL`. Tab. A Tab. B

SELECT Salon.Name AS Salonname, Mitarbeiter.Nachname 
FROM Salon 
LEFT JOIN Mitarbeiter ON Salon.IdSalon = Mitarbeiter.FKSalon;

Ergebnis:

Salonname Nachname
Friedrich List Frisuren Krause
Friedrich List Frisuren Schrotter
Friedrich List Frisuren Hermann
Hammer Haare Krause
Hammer Haare Bitter
Kaiserschnitt NULL

Rechter äußerer Verbund (RIGHT JOIN)

Alle Einträge der rechten Tabelle (Tab. B) werden selektiert, auch wenn keine Verbindung zur linken besteht. Tab. A Tab. B

-- Hier: Alle Salons (Rechts) anzeigen, auch wenn keine Mitarbeiter (Links) zugeordnet sind
SELECT Mitarbeiter.Nachname, Salon.Name AS Salonname
FROM Mitarbeiter 
RIGHT JOIN Salon ON Mitarbeiter.FKSalon = Salon.IdSalon;

Ergebnis:

Nachname Salonname
Krause Friedrich List Frisuren
Schrotter Friedrich List Frisuren
Hermann Friedrich List Frisuren
Krause Hammer Haare
Bitter Hammer Haare
NULL Kaiserschnitt

Gruppierung und Aggregat-Funktionen

Mit GROUP BY werden Datensätze aggregiert (z. B. `COUNT`, `SUM`, `AVG`). Möchte man die Datensätze in einer gruppierten Abfrage filtern, muss HAVING anstatt `WHERE` verwendet werden.

SELECT SUM(Termin.Rechnungsbetrag) AS Umsatz, Mitarbeiter.Nachname AS Mitarbeiter 
FROM TERMIN 
INNER JOIN Mitarbeiter ON Termin.FKMitarbeiter = Mitarbeiter.IdMitarbeiter 
GROUP BY Mitarbeiter.IdMitarbeiter 
HAVING Umsatz > 100;

Ergebnis:

Umsatz Mitarbeiter
106 Schrotter

Unterabfragen (Verschachtelt)

Unterabfragen werden in Klammern gesetzt und liefern Werte für die Hauptabfrage.

-- Termine mit unterdurchschnittlichem Umsatz
SELECT TerminID, Rechnungsbetrag FROM Termin 
WHERE Rechnungsbetrag < (SELECT AVG(Rechnungsbetrag) FROM Termin);

UNION

Mit UNION werden zwei Relationen vereint. Die Spalten müssen vom gleichen Typ sein.

SELECT Mitarbeiter.nachname FROM Mitarbeiter 
UNION 
SELECT Kunde.nachname FROM Kunde;

Reihenfolge der Abarbeitung

Das DBMS arbeitet eine DQL-Abfrage logisch in dieser Reihenfolge ab:

  1. FROM (inkl. JOINs)
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY
  7. LIMIT