Abfragen mit SELECT
AnfängerEinheit 2 von 6 in Kurs: SQL – Datenbanken abfragen mit SELECT, JOIN und GROUP BY
Was du lernst
- Schreibe Abfragen, die ausgewählte Spalten aus einer Tabelle lesen, verstehe die zurückgegebene Ergebnismenge und liste mit DISTINCT die unterschiedlichen Werte einer Spalte auf.
- Eine einfache SELECT-Abfrage schreibenBenenne mit SELECT die anzuzeigenden Spalten und mit FROM die auszulesende Tabelle, beachte die grundlegenden Syntaxregeln und verstehe, wie das Ergebnis aussieht.
- Unterschiedliche Werte mit DISTINCT auflistenEntferne mit SELECT DISTINCT wiederholte Zeilen aus einem Ergebnis und sage voraus, wie viele Zeilen übrig bleiben, auch bei mehreren Spalten oder fehlenden Werten.
- Eine einfache SELECT-Abfrage schreiben
- Behalte nur die Zeilen, die eine Frage beantworten. Schreibe dazu Bedingungen mit Vergleichsoperatoren für Zahlen, Texte und Datumswerte und verknüpfe Bedingungen mit AND, OR und NOT.
- Zahlen mit Vergleichsoperatoren vergleichenWähle mit WHERE und =, <>, <, >, <= und >= Zeilen anhand numerischer Werte aus und wähle den zur Formulierung einer Frage passenden Operator.
- Texte und Datumswerte richtig vergleichenSchreibe Text- und Datumswerte in der richtigen Form, sage voraus, wie Groß- und Kleinschreibung, alphabetische Reihenfolge und Datumsformate einen Vergleich beeinflussen, und vermeide typische Fehler bei Anführungszeichen und Datumswerten.
- Bedingungen mit AND, OR und NOT verknüpfenVerknüpfe mehrere Bedingungen mit AND und OR, kehre eine Bedingung mit NOT um und verwende Klammern, damit die Abfrage genau das prüft, wonach gefragt wird.
- Zahlen mit Vergleichsoperatoren vergleichen
- Formuliere Bedingungen kürzer und genauer: mit IN für Wertelisten, BETWEEN für Bereiche und LIKE für Textmuster. Berücksichtige auch ihre NOT-Formen und typische Fehlerquellen.
- Mit IN gegen eine Werteliste prüfenVerwende IN und NOT IN, um Zeilen zu behalten, deren Wert einem von mehreren aufgeführten Werten entspricht, und verstehe, wie Listen mit AND und fehlenden Werten zusammenwirken.
- Einen Bereich mit BETWEEN auswählenVerwende BETWEEN und NOT BETWEEN für Bereiche aus Zahlen, Datumswerten und Text. Beachte, dass beide Bereichsgrenzen eingeschlossen sind und wo das zu Fehlern führt.
- Mit LIKE nach Textmustern suchenFinde mit LIKE sowie % und _ Text, der mit bestimmten Zeichen beginnt, endet oder sie enthält, und gehe mit Groß- und Kleinschreibung, wörtlichen Platzhalterzeichen und fehlenden Werten um.
- Mit IN gegen eine Werteliste prüfen
- Erkenne NULL als fehlenden Wert, finde ihn mit IS NULL und IS NOT NULL und sage voraus, wie fehlende Werte das Ergebnis aller anderen Arten von Bedingungen verändern.
- Fehlende Werte mit IS NULL findenUnterscheide NULL von null und einer leeren Zeichenkette und finde mit IS NULL und IS NOT NULL Zeilen, in denen ein Wert fehlt oder erfasst ist.
- Vorhersagen, wie sich NULL auf Bedingungen auswirktWende die dreiwertige Logik (wahr, falsch, unbekannt) auf Vergleiche, AND, OR, NOT, IN, BETWEEN und LIKE an und entscheide, ob Zeilen mit fehlenden Werten in eine Antwort gehören.
- Fehlende Werte mit IS NULL finden
- Bringe Ergebniszeilen mit ORDER BY in eine sinnvolle Reihenfolge, sortiere nach mehreren Spalten und gehe dabei mit gleichen und fehlenden Werten um. Gib mit LIMIT und OFFSET die ersten Zeilen oder eine Seite von Zeilen zurück.
- Zeilen mit ORDER BY sortierenSortiere ein Ergebnis nach einer Spalte aufsteigend oder absteigend und sage voraus, wie Zahlen, Datumswerte und Text angeordnet werden.
- Nach mehreren Spalten sortieren und mit gleichen Werten und NULL umgehenSortiere nach mehreren Spalten mit jeweils eigener Sortierrichtung, ergänze nachrangige Sortierkriterien für eine wiederholbare Reihenfolge und lege fest, wo fehlende Werte erscheinen.
- Die ersten Zeilen und einzelne Seiten mit LIMIT und OFFSET ausgebenGib mit LIMIT die ersten Zeilen eines sortierten Ergebnisses zurück, überspringe mit OFFSET Zeilen, um spätere Seiten anzuzeigen, und formuliere dieselbe Anfrage in anderen SQL-Dialekten.
- Zeilen mit ORDER BY sortieren
- Kombiniere alle Klauseln zu korrekten, lesbaren Abfragen, verstehe die Reihenfolge, in der eine Abfrage verarbeitet wird, und übersetze alltägliche Fragen in Abfragen, deren Ergebnisse du prüfst.
- Klauseln richtig anordnen und wissen, wie eine Abfrage verarbeitet wirdSchreibe SELECT, FROM, WHERE, ORDER BY und LIMIT in der vorgeschriebenen Reihenfolge und nutze die logische Verarbeitungsreihenfolge, um vorherzusagen, welche Daten jeder Klausel zur Verfügung stehen.
- Eine Frage in eine Abfrage übersetzen und das Ergebnis prüfenÜbersetze eine alltägliche Frage Schritt für Schritt in eine Abfrage über eine einzelne Tabelle und prüfe dann das Ergebnis auf Grenzwerte, fehlende Werte, Groß- und Kleinschreibung und gleiche Werte.
- Klauseln richtig anordnen und wissen, wie eine Abfrage verarbeitet wird
Abfragen mit SELECT einfach erklärt
1Die anzuzeigenden Daten auswählen
Eine nützliche Abfrage beginnt mit der Auswahl der Tabelle und der Spalten, die deine Frage beantworten. Das Ergebnis kann jeden Datensatz, einige Felder aus jedem Datensatz oder eine Liste unterschiedlicher Werte anzeigen. Du arbeitest mit zwei kleinen Tabellen, sodass du jedes Ergebnis auf die gespeicherten Daten zurückführen kannst. Wenn du die Spaltennamen sorgfältig liest und zwischen Spalten- und Zeilenreihenfolge unterscheidest, verstehst du spätere Filter und Sortierungen leichter.
1.1 SELECT, FROM und die Ergebnistabelle
Eine Abfrage fragt Daten aus einer Datenbank ab. Eine einfache SELECT-Abfrage liest die gespeicherte Tabelle, ohne sie zu ändern. SELECT benennt die anzuzeigenden Spalten und FROM die auszulesende Tabelle.
Die Textbeispiele verwenden den gewöhnlichen Gleichheitsvergleich in SQLite und PostgreSQL, der Groß- und Kleinschreibung beachtet. Einstellungen der Sortierfolge können ändern, wie Text verglichen und sortiert wird.
Zwei Tabellen zum Arbeiten
Die Tabelle employees hat diese acht Zeilen. salary ist das Jahresgehalt in Dollar; hire_date ist Text in der Form YYYY-MM-DD. NULL kennzeichnet einen fehlenden Wert.
| employee_id | first_name | last_name | department | city | salary | hire_date | phone |
|---|---|---|---|---|---|---|---|
| 1 | Ana | Lopez | Sales | Chicago | 52000 | 2019-03-15 | 312-555-0147 |
| 2 | Ben | Carter | IT | Denver | 71000 | 2021-07-01 | NULL |
| 3 | Chloe | Nguyen | Sales | Chicago | 48000 | 2023-01-09 | 312-555-0198 |
| 4 | David | Kim | Marketing | Boston | 60000 | 2020-11-23 | 617-555-0110 |
| 5 | Emma | Brown | Sales | Denver | 65000 | 2018-05-30 | NULL |
| 6 | Farid | Haddad | IT | Chicago | 83000 | 2017-09-12 | 312-555-0175 |
| 7 | Grace | Okafor | NULL | Boston | 45000 | 2024-02-19 | 617-555-0133 |
| 8 | Hugo | O'Neill | Marketing | Chicago | 58000 | 2022-08-05 | NULL |
Die Tabelle products erfasst Preise in Dollar und den Lagerbestand in Stück.
| product_id | name | category | price | stock |
|---|---|---|---|---|
| 1 | Desk Lamp | Lighting | 24,99 | 40 |
| 2 | Floor Lamp | Lighting | 89,00 | 12 |
| 3 | Lamp Shade | Lighting | 15,50 | 0 |
| 4 | Office Chair | Furniture | 149,00 | 8 |
| 5 | Standing Desk | Furniture | 349,00 | 5 |
| 6 | Desk Organizer | Storage | 18,75 | 60 |
| 7 | Bookshelf | Furniture | 120,00 | NULL |
| 8 | Paper Tray | Storage | 9,99 | 25 |
Den Aufbau der Abfrage lesen
SELECT city, first_name
FROM employees;
Die Ergebnismenge ist eine weitere Tabelle: acht Zeilen und zwei Spalten, mit city an erster Stelle. Es gibt keinen Filter, daher trägt jede beschäftigte Person eine Zeile bei. SQL garantiert keine Zeilenreihenfolge, solange du kein ORDER BY ergänzt.
SELECT * FROM products; zeigt alle Spalten in der in der Tabelle definierten Reihenfolge an. Der Stern ist beim Erkunden nützlich. Wenn du in einer gespeicherten Abfrage die Spalten benennst, bleibt das Ergebnis auf das Nötige beschränkt und eine neu hinzugefügte Tabellenspalte ändert seinen Aufbau nicht.
Die Syntax lesbar gestalten
Trenne Spalten durch Kommas, ohne ein abschließendes Komma vor FROM. Beende die Anweisung mit einem Semikolon. Bei Schlüsselwörtern spielt die Groß- und Kleinschreibung keine Rolle, sodass select funktioniert. Großbuchstaben machen Klauseln aber leicht auffindbar. Leerzeichen und Zeilenumbrüche trennen Wörter; sie ändern die Bedeutung dieser Abfrage nicht. Ein ---Kommentar reicht bis zum Ende seiner Zeile.
Namen müssen im Schema gefunden werden können. Führt frist_name zu einem Fehler wegen einer fehlenden Spalte, vergleiche die Schreibweise mit first_name. Standard-SQL verwendet doppelte Anführungszeichen für Namen, die Leerzeichen enthalten oder reservierte Wörter sind, etwa "order date". PostgreSQL wandelt Namen ohne Anführungszeichen in Kleinbuchstaben um, während "City" genau diesen großgeschriebenen Namen sucht. MySQL verwendet normalerweise Graviszeichen; doppelte Anführungszeichen kennzeichnen Namen im Modus ANSI_QUOTES. SQL Server akzeptiert auch eckige Klammern und bei eingeschaltetem QUOTED_IDENTIFIER, seiner Standardeinstellung, doppelte Anführungszeichen.
Wichtige Erkenntnisse
SELECTwählt die angezeigten Spalten;FROMbezeichnet ihre Tabelle.- Die Ergebnisspalten folgen der SELECT-Liste; für eine Zeilenreihenfolge ist
ORDER BYnötig. SELECT *zeigt alle Spalten; ausdrückliche Namen beschränken gespeicherte Abfragen auf das Nötige.- Verwende Kommas zwischen Spalten und ein Semikolon zum Beenden einer Anweisung.
- Vergleiche Namen mit dem Schema und beachte die Regeln der Datenbank für Anführungszeichen um Bezeichner.
1.2 Unterschiedliche Werte und Wertekombinationen
Ein wiederholter Wert in einem Abfrageergebnis ist oft nützlich. Mehrere Beschäftigte können in derselben Stadt wohnen und trotzdem braucht jede Person eine Zeile. Verwende DISTINCT, wenn die Frage nach unterschiedlichen Werten oder unterschiedlichen Kombinationen fragt.
Festlegen, was als Duplikat zählt
SELECT DISTINCT city
FROM employees;
Das Ergebnis enthält Chicago, Denver und Boston, ohne garantierte Reihenfolge. Das einfache SELECT city würde acht Zeilen zurückgeben, weil jede beschäftigte Person eine Stadt beisteuert. Mit DISTINCT wird die Anzeige auf drei unterschiedliche Werte reduziert. Alle acht Datensätze der Beschäftigten bleiben gespeichert.
Der Vergleich umfasst jede ausgewählte Spalte. Betrachte:
SELECT DISTINCT department, city
FROM employees;
Ana und Chloe steuern beide (Sales, Chicago) bei, sodass dieses Paar einmal erscheint. Emma steuert (Sales, Denver) bei, das anders ist und erhalten bleibt. Die anderen Paare sind (IT, Denver), (Marketing, Boston), (IT, Chicago), (NULL, Boston) und (Marketing, Chicago). Es gibt sieben Ergebniszeilen. Wiederholte Abteilungen bleiben erhalten, weil eine Abteilung mit einer anderen Stadt eine andere Ergebniszeile bildet.
Schreibe DISTINCT einmal direkt nach SELECT. Es gilt für die gesamte ausgewählte Zeile. Zwischen Spaltennamen, wie in SELECT department, DISTINCT city, ist es ein Syntaxfehler.
Auf die einbezogenen Spalten achten
Fügst du employee_id zu den ausgewählten Spalten hinzu, wird jede Zeile unterschiedlich. SELECT DISTINCT employee_id, city FROM employees; gibt weiterhin acht Zeilen zurück: Jede ID ist eindeutig, auch wenn sich die Stadt wiederholt. Um „In welchen Städten gibt es Beschäftigte?“ zu beantworten, wähle nur die Stadt. Für „Welche Beschäftigten wohnen in welcher Stadt?“ behalte identifizierende Spalten und erwarte wiederholte Städte.
Beim Entfernen von Duplikaten werden wiederholte NULL-Werte als Duplikate behandelt. SELECT DISTINCT department FROM employees; gibt Sales, IT, Marketing und eine NULL-Zeile zurück. Die NULL-Zeile zeigt, dass eine Abteilung fehlt; sie ist kein vierter Abteilungsname. Diese Duplikatregel unterscheidet sich von NULL = NULL, was in einem Filter unbekannt ergibt.
Textvergleiche folgen einer Sortierfolge, den Regeln der Datenbank für den Abgleich und die Anordnung von Text. Bei den gewöhnlichen Vergleichen dieser SQLite- und PostgreSQL-Beispiele, die Groß- und Kleinschreibung beachten, sind Chicago und chicago unterschiedliche Werte. Eine DISTINCT-Liste kann uneinheitliche Groß- und Kleinschreibung sichtbar machen. Das Entfernen wiederholter Anzeigen korrigiert nicht die Schreibweise in den gespeicherten Daten.
DISTINCT mit einer sortierten Auswahlliste kombinieren
SELECT DISTINCT city
FROM employees
ORDER BY city
LIMIT 2;
Zuerst verschwinden doppelte Städte. Danach werden die drei Städte sortiert. Schließlich bleiben zwei Ergebniszeilen: Boston und Chicago, in dieser Reihenfolge. Würde die Begrenzung zuerst auf die Zeilen der Beschäftigten angewendet, beantwortete das eine andere Frage.
Nimm bei einer DISTINCT-Abfrage die Sortierspalten in die SELECT-Liste auf. PostgreSQL verlangt das; SQLite erlaubt manche Abfragen, die nach einer nicht ausgewählten Spalte sortieren. Die Auswahl zwischen unterschiedlichen verborgenen Werten macht ihre Reihenfolge aber schwer deutbar. Wiederholt sich ein Ergebnis unerwartet, prüfe, welche Spalten du ausgewählt hast, bevor du entscheidest, ob DISTINCT in die Abfrage gehört.
Wichtige Erkenntnisse
DISTINCTentfernt doppelte vollständige Ergebniszeilen, ohne gespeicherte Zeilen zu ändern.- Zusätzliche Spalten ändern, welche Zeilen als Duplikate zählen; ein eindeutiger Schlüssel hält jede Zeile unterschiedlich.
- DISTINCT gruppiert wiederholte NULL-Werte zusammen.
- Duplikate werden entfernt, bevor das sortierte Ergebnis begrenzt wird.
2Die Zeilen behalten, die die Frage beantworten
Durch Filtern wird eine Tabelle zu einer Antwort über bestimmte Datensätze: einen Gehaltsbereich, eine Stadt oder eine Gruppe, die mehrere Bedingungen erfüllt. Kleine Entscheidungen sind wichtig, etwa ob eine Bereichsgrenze zählt und ob zwei Bedingungen beide erfüllt sein müssen. Für numerische Vergleiche, Text- und Datumswerte sowie gruppierte logische Bedingungen gelten jeweils eigene Regeln. Eine Abfrage kann erfolgreich ausgeführt werden und trotzdem die falsche Frage stellen. Deshalb verfolgst du, welche Zeilen jede Prüfung bestehen.
2.1 Zahlen und Grenzwerte
Die WHERE-Klausel behält eine Zeile nur, wenn ihre Bedingung wahr ist. Sie folgt auf FROM und kann jede Spalte der Tabelle prüfen, auch eine Spalte, die du nicht anzeigst.
Formulierung und Operator zuordnen
| Anfrage | Operator | Beispielbedingung |
|---|---|---|
| Gleich | = | stock = 0 |
| Ungleich | <> | stock <> 0 |
| Mehr als | > | salary > 60000 |
| Mindestens | >= | salary >= 60000 |
| Weniger als | < | price < 20.50 |
| Höchstens | <= | price <= 20.50 |
<> ist die Standard-SQL-Schreibweise für „ungleich“. Die fünf hier besprochenen Datenbanken akzeptieren auch !=. Verwende für Gleichheit ein Gleichheitszeichen. SQLite akzeptiert ==, PostgreSQL lehnt diese Form aber ab.
Eine Zeile am Grenzwert verfolgen
SELECT first_name, salary
FROM employees
WHERE salary > 60000;
Ben hat 71.000, Emma 65.000 und Farid 83.000. Das sind die drei passenden Zeilen, ohne festgelegte Reihenfolge. David verdient genau 60.000. Seine Zeile erfüllt > 60000 nicht, weil „mehr als“ Gleichheit ausschließt.
Ändere nur den Operator zu >=. David kommt nun zum Ergebnis hinzu, sodass es vier Zeilen enthält. So unterscheidet sich „mindestens 60.000“ von „mehr als 60.000“. Bei einer hilfreichen Grenzwertprüfung fragst du, was mit einem Wert geschieht, der genau dem Schwellenwert entspricht; Werte weit darüber können diesen Fehler nicht aufdecken.
Bei „höchstens 20,50“ erfüllt ein Preis von 20,50 die Bedingung, ein Preis von 20,51 dagegen nicht. Gibt eine Anfrage sowohl eine Unter- als auch eine Obergrenze an, prüfe jede Grenze einzeln, bevor du die Prüfungen verknüpfst.
Numerische Werte als Zahlen schreiben
Verwende in SQL-Bedingungen nur Ziffern: 60000, ohne Tausenderkomma oder Währungszeichen. Ein Komma trennt SQL-Einträge; WHERE salary > 60,000 ist ein Syntaxfehler. Dezimalwerte werden mit Punkt geschrieben, wie in WHERE price < 20.50. Gehälter und Preise gehören in numerische Spalten, damit Vergleiche ihre numerische Größe berücksichtigen.
Text, der wie eine Zahl aussieht, folgt beim Textvergleich den Regeln für Text. Der Textwert '9' wird nach '10' einsortiert, weil sein erstes Zeichen später kommt. Das sagt etwas über Zeichen aus, nicht darüber, dass neun größer als zehn wäre. Lies den Datentyp der Spalte, bevor du einen unerwarteten Vergleich deutest.
Filtern, ohne die geprüfte Spalte anzuzeigen
SELECT first_name
FROM employees
WHERE salary < 50000;
Chloe und Grace erfüllen die Bedingung. Ihre Gehälter werden zum Prüfen der Zeilen verwendet, fehlen aber im Ergebnis. Du musst das Gehalt nicht zu SELECT hinzufügen, damit der Filter funktioniert. Beim Prüfen einer Abfrage kann es helfen, das Gehalt vorübergehend anzuzeigen, um den Grund für jede passende Zeile zu untersuchen.
Ein Gleichheitsvergleich mit einem Primärschlüssel ermöglicht das direkte Nachschlagen eines Datensatzes: WHERE employee_id = 6 findet Farid. Ein Primärschlüssel identifiziert eine Zeile, sodass dieser Gleichheitsvergleich nicht mehrere Beschäftigte mit derselben ID zurückgeben kann.
Fehlende Daten brauchen besondere Aufmerksamkeit. WHERE stock <> 0 gibt sechs Produkte zurück. Lamp Shade wird ausgelassen, weil sein bekannter Lagerbestand null ist. Bookshelf wird ebenfalls ausgelassen: Sein Lagerbestand ist NULL, sodass der Vergleich unbekannt ist und WHERE die Zeile nicht behält. Eine Ungleichheitsprüfung nimmt fehlende Werte nicht in ihr Ergebnis auf.
Wichtige Erkenntnisse
- WHERE behält nur Zeilen, deren Bedingung wahr ist.
>und<schließen ihre Schwellenwerte aus;>=und<=schließen sie ein.- Schreibe numerische Literale ohne Währungszeichen, Anführungszeichen oder Tausendertrennzeichen.
- Ein Filter kann eine Spalte prüfen, die nicht angezeigt wird.
- Verwende einen Gleichheitsvergleich mit einem Schlüssel, um einen Datensatz nachzuschlagen.
- Gewöhnliche Vergleiche mit NULL passieren einen WHERE-Filter nicht.
2.2 Text, Anführungszeichen und vollständige Datumswerte
Text- und Datumsbedingungen brauchen Werte in einer Form, die die Datenbank interpretieren kann. Ein falsch geschriebener Wert kann stillschweigend keine Zeilen zurückgeben, während ein fehlendes Anführungszeichen dazu führen kann, dass der Wert als Spaltenname gelesen wird.
Einen Wert von einem Namen unterscheiden
SELECT first_name
FROM employees
WHERE city = 'Chicago';
Die einfachen Anführungszeichen machen 'Chicago' zu einem Textwert. Das Ergebnis enthält Ana, Chloe, Farid und Hugo. Ohne Anführungszeichen wird Chicago als Name gelesen, sodass die Datenbank nach einer Spalte mit diesem Namen sucht. Die doppelten Anführungszeichen des Standards kennzeichnen ebenfalls Namen. PostgreSQL lehnt city = "Chicago" ab, wenn keine solche Spalte existiert. Manche SQLite-Konfigurationen akzeptieren aus historischen Gründen Zeichenketten in doppelten Anführungszeichen; verwende für Werte durchgehend einfache Anführungszeichen.
Ein Apostroph innerhalb eines Werts wird verdoppelt:
SELECT first_name
FROM employees
WHERE last_name = 'O''Neill';
Das findet Hugo. Die beiden aufeinanderfolgenden einfachen Anführungszeichen stehen für einen Apostroph innerhalb des Werts; die äußeren Anführungszeichen kennzeichnen dessen Anfang und Ende. Standard-SQL verwendet keinen umgekehrten Schrägstrich als Escape-Zeichen für diesen Apostroph.
Die Vergleichsregeln prüfen
Eine Sortierfolge steuert die Gleichheit und Sortierung von Text, einschließlich der Behandlung von Groß- und Kleinschreibung und Buchstaben mit Akzenten. Bei den hier verwendeten gewöhnlichen SQLite- und PostgreSQL-Vergleichen, die Groß- und Kleinschreibung beachten, unterscheiden sich 'Chicago' und 'chicago'. WHERE city = 'chicago' gibt keine Zeilen zurück. MySQL und SQL Server verwenden häufig Sortierfolgen, die Groß- und Kleinschreibung ignorieren, sodass ihre üblichen Einstellungen beide Schreibweisen abgleichen können.
Auch Bereichsvergleiche von Text folgen der Sortierfolge. Bei diesen Namen gibt WHERE last_name < 'M' Brown, Carter, Haddad, Kim und Lopez zurück. Werte werden von links verglichen. Ein längerer Wert, der mit denselben Zeichen beginnt, kommt nach seinem Präfix: 'Martin' steht nach 'M'. Eine Grenze bei 'M' ist nicht dasselbe wie „alle Namen, die mit M beginnen“.
Das Jahr zuerst setzen
Die Beispielspalte hire_date speichert vollständige Datumswerte als Text: Jahr, Monat, dann Tag, jeweils mit fester Länge. Dadurch stimmt die Textreihenfolge mit der Kalenderreihenfolge überein.
SELECT first_name, hire_date
FROM employees
WHERE hire_date >= '2022-01-01';
Chloe, Grace und Hugo erfüllen die Bedingung. PostgreSQL hat auch einen echten DATE-Typ, der dieses Literal akzeptiert. Seine typisierte Standardschreibweise ist DATE '2022-01-01'; SQLite verwendet diese Syntax für typisierte Literale nicht.
Eine lokale Datumszeichenkette wie '03/04/2024' ist in einer Datumsspalte mehrdeutig, weil sie je nach Einstellung den 4. März oder den 3. April bedeuten kann. Als Text gespeicherte Datumswerte mit dem Monat an erster Stelle werden zuerst nach dem Monat und dann nach dem Jahr verglichen. So wird '12/01/2021' nach '03/15/2024' einsortiert, obwohl das erste Kalenderdatum früher liegt.
Die vollständige Datumsgrenze übersetzen
„Nach 2022 eingestellt“ bedeutet ab '2023-01-01'. Ein Textvergleich mit '2022' lässt dagegen auch das Einstellungsdatum '2022-08-05' von Hugo zu: Der längere Text wird nach dem übereinstimmenden Präfix einsortiert.
Enthält eine Spalte Uhrzeiten, wählt ein Gleichheitsvergleich mit einem Datum allein nicht jede Uhrzeit an diesem Tag aus. Um den 31. März 2024 einzuschließen, verwende ordered_at >= '2024-03-31' AND ordered_at < '2024-04-01'. Das behält alle Uhrzeiten vom Beginn des 31. März bis zum Beginn des 1. April, ohne diesen einzuschließen.
Wichtige Erkenntnisse
- Verwende einfache Anführungszeichen für Textwerte; verdopple einen Apostroph innerhalb eines Werts.
- Die Sortierfolge bestimmt, wie Groß- und Kleinschreibung und Zeichen in Texten verglichen werden.
- Verwende vollständige Datumswerte in der Form
YYYY-MM-DD, damit Textdatumswerte mit fester Länge chronologisch sortiert werden. - Um einen ganzen Tag mit Uhrzeiten abzudecken, schließe seinen Anfang ein und den Anfang des nächsten Tages aus.
2.3 AND, OR, NOT und gruppierte Bedingungen
Eine Zeile muss möglicherweise mehrere Prüfungen bestehen. AND verlangt, dass beide Bedingungen wahr sind. OR verlangt, dass mindestens eine wahr ist. NOT kehrt wahr und falsch um; ist eine Bedingung wegen NULL unbekannt, lässt NOT sie unbekannt.
Entscheiden, ob beide Prüfungen erfüllt sein müssen
SELECT first_name
FROM employees
WHERE department = 'Sales' AND city = 'Chicago';
Ana und Chloe bestehen beide Prüfungen. Emma arbeitet in Sales, wohnt aber in Denver und erfüllt dieses AND daher nicht. Ersetzt man AND durch OR, kommen auch Emma, Farid und Hugo hinzu: Die fünf passenden Beschäftigten erfüllen eine oder beide Prüfungen.
Eine zusätzliche AND-Bedingung kann das Ergebnis gleich lassen oder verkleinern. Eine zusätzliche OR-Bedingung kann es gleich lassen oder vergrößern. Das ermöglicht dir eine schnelle Prüfung, wenn du einen Filter schrittweise aufbaust.
Jeder Vergleich muss vollständig sein. Schreibe department = 'IT' OR department = 'Marketing' und wiederhole dabei Spalte und Operator. department = 'IT' OR 'Marketing' drückt den zweiten Vergleich nicht aus. PostgreSQL lehnt dies ab; SQLite behandelt den Text allein als falsch und gibt nur Beschäftigte aus IT zurück. Schreibe ebenso salary > 50000 AND salary < 70000, mit salary auf beiden Seiten von AND.
Gruppen von Alternativen übersetzen
„Beschäftigte in Boston und Denver“ fragt gewöhnlich nach Personen in einer der beiden Städte. Jede Zeile hat eine Stadt, verwende daher city = 'Boston' OR city = 'Denver'. Das gibt Ben, David, Emma und Grace zurück. Ein AND zwischen diesen Gleichheitsvergleichen verlangt, dass ein Stadtwert beide Orte zugleich ist, und gibt keine Zeilen zurück.
Werden Operatoren gemischt, wird NOT vor AND und AND vor OR ausgewertet. Ohne Klammern:
WHERE department = 'Sales'
OR department = 'Marketing' AND city = 'Chicago'
Das bedeutet Beschäftigte aus Sales an beliebigen Orten und zusätzlich Beschäftigte aus Marketing in Chicago. Emma erfüllt die Bedingung, weil der Vergleich mit Sales ausreicht. Um beide Abteilungen auf Chicago zu beschränken, gruppiere die Alternativen:
SELECT first_name
FROM employees
WHERE (department = 'Sales' OR department = 'Marketing')
AND city = 'Chicago';
Nun erfüllen Ana, Chloe und Hugo die Bedingung. Die Klammern stellen beide Abteilungsoptionen unter eine gemeinsame Stadtbedingung. Verwende sie, um einen gemischten AND/OR-Filter verständlich zu machen, auch wenn die Standardreihenfolge bereits richtig wäre.
Eine ganze Gruppe umkehren
NOT (city = 'Chicago' OR city = 'Denver') gibt David und Grace in Boston zurück. Keine der beiden aufgeführten Städte ist erlaubt. Für diese Werte ist das gleichbedeutend mit city <> 'Chicago' AND city <> 'Denver'.
OR zwischen diesen beiden Ungleichheitsprüfungen zu verwenden, ist eine häufige Falle. Eine Chicago-Zeile unterscheidet sich von Denver und eine Denver-Zeile von Chicago. Alle Beschäftigten mit einer erfassten Stadt bestehen mindestens eine Prüfung, sodass OR keine der beiden Städte ausschließt.
Baue eine komplexe Bedingung Stück für Stück auf. Prüfe die Zeilen nach der ersten Prüfung und dann nach dem Hinzufügen der nächsten. Du kannst die beiden Seiten eines AND oder eines OR vertauschen, ohne die Antwort zu ändern. Wähle die Anordnung, bei der die Gruppen am leichtesten zu lesen sind.
Wichtige Erkenntnisse
- AND braucht beide Bedingungen; OR braucht mindestens eine.
- Schreibe auf jeder Seite eines logischen Operators einen vollständigen Vergleich.
- NOT wird vor AND ausgewertet, danach folgt OR; Klammern machen die beabsichtigte Gruppierung ausdrücklich.
- Alternativen für eine Spalte brauchen gewöhnlich OR, auch wenn die Anfrage „und“ sagt.
- Um beide Möglichkeiten auszuschließen, verneine die OR-Gruppe oder verbinde die beiden Ausschlüsse mit AND.
3Listen, Bereiche und Textmuster abgleichen
Manche Fragen verlangen mehrere genaue Auswahlmöglichkeiten, andere einen Wertebereich oder einen Teil eines Namens. IN, BETWEEN und LIKE geben jeder Art von Anfrage eine klare Form. Die Wahl beginnt damit, was eine Übereinstimmung bedeutet: ein ganzer Wert, ein Wert zwischen Bereichsgrenzen oder Text, der auf ein Muster passt. Du prüfst auch fehlende Werte und Einzelheiten, die eine Antwort verändern, darunter eingeschlossene Bereichsgrenzen, die Platzierung von Platzhaltern und die Beachtung der Groß- und Kleinschreibung.
3.1 Listen genauer Auswahlwerte mit IN
Verwende IN, wenn eine Spalte einem beliebigen Wert einer Liste entsprechen darf. Es verkürzt eine Gruppe von Gleichheitsvergleichen, die durch OR verbunden sind, und behält dabei ihre Bedeutung.
Eine Liste von Alternativen erstellen
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing');
Ben, David, Farid und Hugo erfüllen die Bedingung. Jede dieser Personen hat einen der beiden Abteilungswerte. Dieselbe Prüfung ließe sich als department = 'IT' OR department = 'Marketing' schreiben.
Setze Listeneinträge in Klammern und trenne sie durch Kommas. Setze Text in einfache Anführungszeichen; numerische Werte bleiben ohne Anführungszeichen. Zum Beispiel wählt employee_id IN (2, 4, 6) Ben, David und Farid aus. Die Reihenfolge der Listeneinträge sortiert das Ergebnis nicht. Ein wiederholter Eintrag wiederholt keine passende Zeile: IN (6, 2, 2, 4) wählt dieselben Datensätze aus. Verwende ORDER BY, wenn du eine Ergebnisreihenfolge brauchst.
IN gleicht ganze Werte nach denselben Vergleichsregeln wie ein Gleichheitsvergleich ab. city IN ('Chi') trifft nicht auf Chicago zu. Auch city IN ('chicago') trifft bei den hier verwendeten gewöhnlichen Vergleichen, die Groß- und Kleinschreibung beachten, nicht darauf zu. Für die Suche nach einem Teilwert brauchst du LIKE; die Behandlung der Groß- und Kleinschreibung hängt von der Sortierfolge ab.
Eine weitere Regel auf jede Auswahl anwenden
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing')
AND city = 'Chicago';
Farid und Hugo erfüllen die Bedingung. IN ist eine Bedingung, sodass AND die Stadtprüfung auf die gesamte Abteilungsauswahl anwendet. Setze in der ausgeschriebenen OR-Variante Klammern um die beiden Abteilungsvergleiche. Ohne sie lässt department = 'IT' OR department = 'Marketing' AND city = 'Chicago' auch Ben zu, weil AND stärker bindet und die Stadtregel nur für Marketing gilt.
Die aufgeführten Werte ausschließen
WHERE city NOT IN ('Chicago', 'Denver') gibt David und Grace zurück. Eine erfasste Stadt erfüllt die Bedingung nur, wenn sie sich von beiden Einträgen unterscheidet. Diese Form ist für mehrere Ausschlüsse nützlich und vermeidet den Fehler, Ungleichheitsbedingungen mit OR zu verbinden.
Fehlende Werte erfüllen keine der beiden Formen. Grace hat die Abteilung NULL, sodass department NOT IN ('Sales') sie nicht einschließt. Die Datenbank kann nicht feststellen, dass sich die fehlende Abteilung von Sales unterscheidet. Um auch Beschäftigte ohne zugewiesene Abteilung einzuschließen, schreibe department NOT IN ('Sales') OR department IS NULL.
Ein NULL innerhalb einer NOT-IN-Liste verursacht ein umfassenderes Problem. department NOT IN ('Sales', NULL) verlangt sowohl department <> 'Sales' als auch department <> NULL. Der zweite Vergleich ist immer unbekannt, sodass die kombinierte Prüfung nie wahr ist und WHERE keine Zeilen zurückgibt. Halte Prüfungen auf fehlende Werte von der Werteliste getrennt.
Bei IN ist eine tatsächliche Übereinstimmung weiterhin erfolgreich, auch wenn ein anderer Listeneintrag NULL ist. department IN ('Sales', NULL) behält die drei Beschäftigten aus Sales, nimmt Grace aber nicht hinzu. Verwende IS NULL, um fehlende Werte ausdrücklich anzufordern.
Eine gewöhnliche SQL-IN-Liste braucht mindestens einen Eintrag. PostgreSQL lehnt IN () ab; SQLite akzeptiert es als falsch. Erstellt ein Programm eine Liste aus der Auswahl von Nutzern, behandle eine leere Liste vor dem Absenden der Abfrage, damit das Verhalten über Datenbanken hinweg bewusst festgelegt ist.
Wichtige Erkenntnisse
- IN gleicht jeden ganzen Wert in seiner geklammerten, durch Kommas getrennten Liste ab.
- Listenreihenfolge und wiederholte Einträge bestimmen weder die Ergebnisreihenfolge noch vervielfachen sie passende Zeilen.
- IN wird als eine Bedingung mit AND verknüpft.
- NOT IN schließt aufgeführte Werte aus, schließt aber fehlende Werte nicht ein.
- Ein NULL innerhalb einer NOT-IN-Liste verhindert, dass irgendeine Zeile die WHERE-Prüfung besteht.
3.2 Bereiche und eingeschlossene Bereichsgrenzen
BETWEEN prüft einen Bereich, wobei beide Grenzen eingeschlossen sind. Verwende es, wenn „von“ und „bis“ die genannten Grenzwerte einschließen; verwende ausdrückliche Vergleiche, wenn eine der Grenzen ausgeschlossen werden muss.
Die beiden Grenzen prüfen
SELECT name, price
FROM products
WHERE price BETWEEN 15.50 AND 89.00;
Desk Lamp, Floor Lamp, Lamp Shade und Desk Organizer erfüllen die Bedingung. Floor Lamp kostet genau 89,00 und Lamp Shade genau 15,50, sodass beide erhalten bleiben. Die Bedingung bedeutet price >= 15.50 AND price <= 89.00.
Setze den kleineren Wert zuerst. price BETWEEN 89.00 AND 15.50 fragt nach einem Preis von mindestens 89,00 und höchstens 15,50. Die Syntax ist gültig, aber es gibt keine Übereinstimmungen. Ein gewöhnliches BETWEEN ordnet die Bereichsgrenzen nicht für dich um. PostgreSQL bietet dafür BETWEEN SYMMETRIC an, verwende aber für eine auch mit SQLite genutzte Abfrage die Form mit dem kleineren Wert zuerst.
Für „mehr als 15,50 und weniger als 89,00“ schreibe price > 15.50 AND price < 89.00. Nur Desk Lamp und Desk Organizer erfüllen die Bedingung. Dieser Unterschied betrifft die Bereichsgrenzen der Frage, nicht die Anzeige des Ergebnisses.
Außerhalb eines Bereichs
price NOT BETWEEN 20 AND 100 bedeutet price < 20 OR price > 100. Es gibt Lamp Shade, Office Chair, Standing Desk, Desk Organizer, Bookshelf und Paper Tray zurück. Werte von genau 20 oder 100 lägen innerhalb des ursprünglichen Bereichs und erfüllten NOT BETWEEN nicht.
Ein fehlender geprüfter Wert ergibt bei beiden Prüfungen unbekannt. Für den Lagerbestand wählt BETWEEN 5 AND 40 fünf Produkte aus und NOT BETWEEN zwei: Lamp Shade mit 0 und Desk Organizer mit 60. Bookshelf hat den Lagerbestand NULL und gehört zu keinem der beiden Ergebnisse. Ein Bereich und seine Verneinung müssen daher nicht jede gespeicherte Zeile abdecken.
Datumswerte und Uhrzeiten
Vollständige Datumszeichenketten in der Reihenfolge YYYY-MM-DD erlauben Datumsbereiche. hire_date BETWEEN '2020-01-01' AND '2022-12-31' wählt Ben, David und Hugo aus und deckt in dieser Spalte, die nur Datumswerte enthält, alle drei Kalenderjahre ab.
Eine Spalte mit Uhrzeiten braucht für einen ganzen Monat eine andere obere Grenze. Eine Bereichsgrenze, die nur ein Datum enthält, bedeutet in einer Zeitstempelspalte Mitternacht zu Beginn dieses Tages. Als Text wird selbst '2024-03-31 00:00:00' nach dem kürzeren Präfix '2024-03-31' einsortiert. Um alle Uhrzeiten im März einzuschließen, verwende:
WHERE ordered_at >= '2024-03-01'
AND ordered_at < '2024-04-01'
Das schließt den Beginn des März ein und endet unmittelbar vor dem April, ohne den letzten Sekundenbruchteil am 31. März erraten zu müssen.
Textbereiche und die zwei Funktionen von AND
Bereichsgrenzen bei Text sind vollständige Werte. last_name BETWEEN 'A' AND 'C' schließt Brown ein, aber Carter aus, weil Carter nach seinem Präfix C einsortiert wird. Nach diesen Textregeln deckt last_name >= 'A' AND last_name < 'D' Namen ab, die mit A, B oder C beginnen, und gibt Brown und Carter zurück.
In price BETWEEN 10 AND 100 AND category = 'Lighting' trennt das erste AND die Bereichsgrenzen; das zweite verbindet die Bereichsprüfung mit der Kategorieprüfung. Die passenden Produkte sind Desk Lamp, Floor Lamp und Lamp Shade. Zeilenumbrüche können die beiden Funktionen leichter erkennbar machen.
Wichtige Erkenntnisse
- BETWEEN schließt beide Bereichsgrenzen ein und erwartet die untere Grenze zuerst.
- NOT BETWEEN wählt Werte unterhalb der unteren oder oberhalb der oberen Grenze aus.
- Mit ausdrücklichen Vergleichen kannst du eine oder beide Bereichsgrenzen ausschließen.
- Für einen ganzen Monat mit Uhrzeiten schließe seinen Anfang ein und ende vor dem nächsten Monat.
- Eine Bereichsgrenze bei Text ist ein vollständiger Wert, nicht jeder Wert mit diesem Anfangsbuchstaben.
- NULL in der geprüften Spalte erfüllt keine der beiden Bereichsprüfungen.
3.3 Textmuster mit LIKE
LIKE gleicht Text mit einem Muster ab. Verwende es, um nach einem Anfang, einem Ende oder einem Textteil zu suchen, wenn ein Gleichheitsvergleich einen vollständig übereinstimmenden Wert verlangen würde.
Die Platzhalter setzen
| Muster | Bedeutung | Passende Produktnamen |
|---|---|---|
'Lamp%' | Beginnt mit Lamp | Lamp Shade |
'%Lamp' | Endet mit Lamp | Desk Lamp, Floor Lamp |
'%Lamp%' | Enthält Lamp | Desk Lamp, Floor Lamp, Lamp Shade |
'Lamp' | Genau Lamp | Keine |
Das Muster muss auf den ganzen Wert passen. % kann null oder mehr Zeichen darstellen, einschließlich Leerzeichen. In '%Lamp%' kann jedes der beiden Prozentzeichen auch auf nichts passen, sodass der Text mit Lamp beginnen oder enden und es auch in der Mitte enthalten kann.
_ steht für genau ein Zeichen. last_name LIKE '_im' findet Kim. Vier Unterstriche in first_name LIKE '____' finden Emma und Hugo, die Vornamen mit genau vier Buchstaben. Der Unterstrich steht nicht für ein optionales Zeichen.
SELECT first_name, phone
FROM employees
WHERE phone LIKE '312-%';
Ana, Chloe und Farid erfüllen die Bedingung, weil der erfasste Text ihrer Telefonnummern mit 312- beginnt. Das Prozentzeichen deckt alle übrigen Zeichen ab.
Operator und Regel für Groß- und Kleinschreibung wählen
Platzhalter gehören zu LIKE-Mustern. name = '%Lamp%' sucht nach tatsächlichen Prozentzeichen und gibt hier keine Produkte zurück. Die Platzhalter * und ? aus der Dateisuche haben bei LIKE keine besondere Bedeutung; name LIKE 'Desk*' sucht nach einem tatsächlichen Sternchen nach Desk.
LIKE in SQLite ignoriert normalerweise die Groß- und Kleinschreibung bei den ASCII-Buchstaben A bis Z, während das gewöhnliche LIKE in PostgreSQL sie beachtet. name LIKE '%desk%' findet daher in SQLite Desk Lamp, Standing Desk und Desk Organizer, in PostgreSQL bei einer Sortierfolge, die Groß- und Kleinschreibung beachtet, dagegen keine Zeilen. PostgreSQL bietet außerdem ILIKE an, das Groß- und Kleinschreibung ignoriert. Das Verhalten von MySQL folgt der Sortierfolge.
Für die hier verwendeten ASCII-Produktnamen liefert LOWER(name) LIKE '%desk%' in SQLite und PostgreSQL dieselben Treffer: LOWER wandelt den Namen vor dem Abgleich in Kleinbuchstaben um. Die Umwandlung der Groß- und Kleinschreibung für andere Schriftsysteme hängt von Datenbank- und Sprachregeln ab. Auch der Gleichheitsvergleich in SQLite unterscheidet sich von seinem LIKE: city = 'chicago' findet Chicago bei der standardmäßigen binären Sortierfolge nicht, obwohl city LIKE 'chicago' es findet.
Nach einem tatsächlichen Platzhalterzeichen suchen
Um nach einem tatsächlichen Unterstrich zu suchen, wähle ein Escape-Zeichen:
WHERE code LIKE 'SPRING!_%' ESCAPE '!'
In einer Tabelle mit Rabattcodes trifft dies auf 'SPRING_10', aber nicht auf 'SPRINGS10' zu. Das !_ steht für einen tatsächlichen Unterstrich; das letzte % steht weiterhin für eine Zeichenfolge. Verwende denselben Ansatz mit !% für ein tatsächliches Prozentzeichen. Ein ausdrücklich geschriebenes ESCAPE vermeidet die Abhängigkeit von den Standardeinstellungen der Datenbank; PostgreSQL verwendet normalerweise einen umgekehrten Schrägstrich und SQLite hat kein standardmäßiges Escape-Zeichen.
Verneinung und Suchumfang
name NOT LIKE '%Lamp%' gibt die anderen fünf Produkte zurück. Fehlender Text erfüllt weder LIKE noch NOT LIKE. Von den Telefonnummern der Beschäftigten passen drei auf '312-%', zwei erfasste Telefonnummern passen nicht und die drei NULL-Telefonnummern erscheinen in keinem der beiden Ergebnisse.
Ein führendes % gibt einem gewöhnlichen Index keinen festen Anfangstext, auf den er die Suche eingrenzen kann, sodass möglicherweise ein großer Teil der Tabelle durchsucht wird. Ein fester Anfang wie 'Desk%' kann einem geeigneten Index helfen. Verwende für Datumswerte Datumsbereiche: LIKE funktioniert bei diesen Textdatumswerten, aber PostgreSQL verlangt eine Umwandlung, bevor LIKE auf eine echte DATE-Spalte angewendet wird.
Wichtige Erkenntnisse
- LIKE gleicht den ganzen Wert ab;
%steht für beliebig viele Zeichen und_für genau eines. - Setze
%an den Anfang, ans Ende oder an beide Stellen, um festzulegen, wo ein Textteil vorkommen darf. - Die Behandlung der Groß- und Kleinschreibung hängt von Datenbank und Sortierfolge ab; LOWER hilft bei diesen ASCII-Namen.
- ESCAPE ermöglicht, dass ein Platzhalter für sein tatsächliches Zeichen steht.
- NULL erfüllt weder LIKE noch NOT LIKE.
- Führende Platzhalter können dazu führen, dass bei einer Suche mehr Daten durchsucht werden; verwende für Datumswerte Bereiche.
4Fehlende Werte berücksichtigen
Fehlende Daten verändern, welche Datensätze ein Filter finden kann. Ein Lagerbestand von null, eine leere Zeichenkette für eine Telefonnummer und ein nicht erfasster Wert sagen Unterschiedliches aus, auch wenn ein Abfragewerkzeug manche Zellen gleich aussehen lässt. Du verwendest ausdrückliche Prüfungen auf fehlende Werte und verfolgst den dritten Wahrheitswert, unbekannt. Diese Regeln erklären, warum ein Filter und sein Gegenteil dieselben Zeilen auslassen können und wie du diese Zeilen einbeziehst, wenn die Frage es verlangt.
4.1 NULL, null und leere Zeichenketten
NULL kennzeichnet einen fehlenden Wert: Ein Wert kann unbekannt, nicht erfasst oder nicht anwendbar sein. Er unterscheidet sich von einer bekannten Null oder einem bekannten Text ohne Zeichen.
Verstehen, was ein fehlender Wert bedeutet
Lamp Shade hat stock = 0. Die erfasste Stückzahl ist null, das Produkt ist also nicht vorrätig. Bookshelf hat stock NULL: Die Stückzahl wurde nicht erfasst. Die Datenbank kann dir weder sagen, dass null Stück vorhanden sind, noch eine andere Anzahl nennen.
Der Unterschied verändert, welche Frage du beantworten kannst:
| Frage | Bedingung | Ergebnis |
|---|---|---|
| Welche Produkte sind nicht vorrätig? | stock = 0 | Lamp Shade |
| Welche Lagerbestände sind unbekannt? | stock IS NULL | Bookshelf |
| Welche Stückzahlen sind erfasst? | stock IS NOT NULL | Die anderen sieben Produkte |
Eine leer aussehende Zelle in einem Abfragewerkzeug reicht nicht aus, um diese Zustände zu unterscheiden. Manche Werkzeuge zeigen NULL als leere Zelle an, andere schreiben NULL. Prüfe den gespeicherten Wert direkt.
Prüfungen auf fehlende Werte verwenden
SELECT first_name
FROM employees
WHERE phone IS NULL;
Für Ben, Emma und Hugo ist keine Telefonnummer erfasst. IS NULL ergibt für ihre fehlenden Werte wahr. Um die fünf Beschäftigten mit erfasster Telefonnummer zu finden, verwende phone IS NOT NULL: Ana, Chloe, David, Farid und Grace.
Schreibe nicht phone = NULL, um fehlende Telefonnummern zu finden. Ein gewöhnlicher Vergleich mit NULL ergibt unbekannt, selbst wenn beide Seiten NULL sind. WHERE behält nur wahre Zeilen, sodass = NULL keine zurückgibt. <> NULL hat dasselbe Problem. IS NULL prüft auf die Kennzeichnung für einen fehlenden Wert und ergibt für diese Werte einzelner Spalten eindeutig wahr oder falsch.
Die Form NOT phone IS NULL findet in SQLite und PostgreSQL ebenfalls vorhandene Telefonnummern, aber bei phone IS NOT NULL ist die beabsichtigte Prüfung leichter zu lesen.
Drei Arten von Text unterscheiden
| SQL-Ausdruck | Was er darstellt |
|---|---|
NULL | Einen fehlenden Wert |
'' | Einen bekannten Textwert mit null Zeichen |
'NULL' | Vier gewöhnliche Buchstaben |
SQLite, PostgreSQL, MySQL und SQL Server unterscheiden eine leere Zeichenkette von NULL. phone = '' würde leere Zeichenketten finden, nicht die fehlenden Telefonnummern von Ben, Emma oder Hugo. Kann eine Spalte beides enthalten, verwende phone IS NULL OR phone = '', um beide Zustände zu finden. Oracle behandelt einen leeren Textwert als NULL, sodass sich dieser Unterschied beim Wechsel der Datenbank ändert.
Formulierung und Schema anwenden
„Fehlend“, „nicht erfasst“ und „nicht zugewiesen“ weisen auf IS NULL hin. department IS NULL findet Grace. Ihre fehlende Abteilung bedeutet weder, dass der Abteilungstext das Wort 'NULL' ist, noch lässt sich daraus ermitteln, zu welcher Abteilung sie gehört.
Die Tabellendefinition kann eine Spalte als NOT NULL kennzeichnen. Das bedeutet, dass eine gespeicherte Zeile in dieser Spalte kein NULL enthalten kann. Eine IS-NULL-Abfrage auf einer solchen Spalte gibt keine Zeilen zurück. Prüfe diese Regel beim Lesen eines Schemas: Spalten, die fehlende Daten erlauben, brauchen besondere Aufmerksamkeit, wenn du Ausschlüsse erstellst oder Bedingungen verknüpfst.
Wichtige Erkenntnisse
- NULL kennzeichnet einen fehlenden Wert; null und eine leere Zeichenkette sind bekannte Werte.
- IS NULL findet fehlende Werte und IS NOT NULL vorhandene Werte.
= NULLund<> NULLkönnen durch gewöhnliche Vergleiche keine Zeilen finden.'NULL'in Anführungszeichen ist Text, und Oracle behandelt leere Zeichenketten anders als die anderen gezeigten Datenbanken.- Eine NOT-NULL-Spalte kann kein NULL speichern.
4.2 Wahr, falsch und unbekannt
Eine Bedingung kann in SQL wahr, falsch oder unbekannt sein. Fehlende Werte machen den dritten Zustand nötig: Ohne eine erfasste Stückzahl kann eine Datenbank nicht feststellen, ob diese über einem Schwellenwert liegt.
Eine Bedingung und ihr Gegenteil
Für Bookshelf ist stock > 10 unbekannt, weil der Lagerbestand NULL ist. Dasselbe gilt für stock <= 10. WHERE behält nur wahre Bedingungen und lässt sowohl falsche als auch unbekannte aus.
In der Produkttabelle gibt stock > 10 vier Zeilen zurück und stock <= 10 drei. Zusammen erfassen sie sieben der acht Produkte. Bookshelf fehlt in beiden Ergebnissen. NOT stellt die Zeile nicht wieder her: NOT unbekannt ist unbekannt, sodass NOT (stock > 10) weiterhin nur die drei bekannten Stückzahlen von höchstens 10 auswählt.
Das unterscheidet sich von einem Wert, der eine Bedingung nicht erfüllt. Die bekannte Null von Lamp Shade macht stock > 10 falsch, sodass NOT den Wahrheitswert in wahr umkehrt. Eine fehlende Stückzahl liefert keinen solchen eindeutigen Vergleich, den man umkehren könnte.
Unbekannt mit einer weiteren Prüfung verknüpfen
| Verknüpfung | Ergebnis |
|---|---|
| Unbekannt AND falsch | Falsch |
| Unbekannt AND wahr | Unbekannt |
| Unbekannt AND unbekannt | Unbekannt |
| Unbekannt OR wahr | Wahr |
| Unbekannt OR falsch | Unbekannt |
| Unbekannt OR unbekannt | Unbekannt |
Bookshelf kostet 120,00. In stock > 10 OR price > 100 ist die Preisbedingung wahr. OR braucht nur einen wahren Teil, sodass die Zeile erhalten bleibt, obwohl der Vergleich des Lagerbestands unbekannt ist. In stock > 10 AND price > 100 bleibt die Lagerbedingung ungeklärt, sodass das Ergebnis unbekannt ist und die Zeile ausgelassen wird.
Fehlende Werte bewusst einschließen
SELECT first_name
FROM employees
WHERE department <> 'Sales'
OR department IS NULL;
Das gibt Ben, David, Farid, Hugo und Grace zurück. Der Vergleich allein würde vier zurückgeben und Grace auslassen. Der IS-NULL-Zweig schließt Beschäftigte ohne zugewiesene Abteilung ausdrücklich ein. Ob solche Beschäftigten zu „außerhalb von Sales“ gehören, ist eine Frage der beabsichtigten Antwort; die Abfrage muss diese Entscheidung ausdrücken.
Ein NULL-Wert in einer NOT-IN-Liste kann das gesamte Ergebnis verhindern. department NOT IN ('Sales', NULL) bedeutet, dass sich die Abteilung von Sales und von NULL unterscheiden muss. Der zweite Vergleich ist für jede Zeile unbekannt, sodass die vollständige Bedingung nie wahr ist. IN behält tatsächliche Übereinstimmungen weiterhin: department IN ('Sales', NULL) wählt die drei Beschäftigten aus Sales aus, findet Grace aber nicht.
Ein fehlender geprüfter Wert ergibt auch bei LIKE und einem gewöhnlichen BETWEEN-Bereich unbekannt. IS NULL und IS NOT NULL liefern für diese einzelnen Spalten eindeutige Antworten. Prüfe fehlende Werte mit diesen Tests gesondert, wenn eine Zeilenanzahl überraschend erscheint.
Wissen, wann NULL-Werte gruppiert werden
NULL = NULL bleibt unbekannt; von zwei fehlenden Telefonnummern weiß man nicht, ob sie dieselbe Nummer sind. DISTINCT behandelt wiederholte fehlende Werte dagegen als Duplikate, und ORDER BY platziert sie zusammen. Für einen Vergleich, der zwei NULL-Werte bewusst als gleich behandelt, bieten SQLite und PostgreSQL auch IS NOT DISTINCT FROM an.
Wichtige Erkenntnisse
- WHERE behält wahre Zeilen und entfernt falsche und unbekannte Zeilen.
- NOT lässt unbekannt unverändert; auch verneinte Filter können NULL-Zeilen auslassen.
- Ein wahrer OR-Zweig kann eine Zeile mit einem anderen unbekannten Zweig erhalten.
- Ergänze IS NULL ausdrücklich, wenn fehlende Werte zur Antwort gehören sollen.
- Ein NULL in einer NOT-IN-Liste verhindert, dass eine Zeile diesen Ausschlussfilter passiert.
- Beim Entfernen von Duplikaten werden NULL-Werte gruppiert, obwohl der gewöhnliche Gleichheitsvergleich von NULL-Werten unbekannt ist.
5Ergebnisse sortieren und eine Seite auswählen
Eine Zeilenbegrenzung wird erst aussagekräftig, wenn du entscheidest, welche Zeilen zuerst kommen sollen. Die Sortierung kann Zahlen, Texte oder Datumswerte ordnen, und spätere Sortierspalten entscheiden bei gleichen Werten in vorherigen Spalten. Fehlende Werte und Zeilen mit gleichen Sortierwerten brauchen Aufmerksamkeit, wenn eine Auswahlliste oder eine Seite wiederholbar sein muss. Du erstellst eindeutige Sortierreihenfolgen, begrenzt nach dem Filtern und erkennst die unterschiedlichen Schreibweisen für Zeilenbegrenzungen in verbreiteten Datenbanksystemen.
5.1 Aufsteigende und absteigende Reihenfolge
ORDER BY legt die Reihenfolge der Ergebniszeilen fest. Ohne ORDER BY verspricht SQL nicht, welche Zeile zuerst erscheint, selbst wenn eine kleine Tabelle scheinbar jedes Mal dieselbe Reihenfolge zurückgibt.
Die Richtung wählen
| Richtung | Zahlen | Vollständige Datumswerte | Text |
|---|---|---|---|
ASC | Kleinste zuerst | Früheste zuerst | Reihenfolge der Sortierfolge |
DESC | Größte zuerst | Neueste zuerst | Umgekehrte Reihenfolge der Sortierfolge |
ASC ist die Voreinstellung. ORDER BY salary und ORDER BY salary ASC verlangen dieselbe Richtung. „Höchstes Gehalt zuerst“ verlangt ORDER BY salary DESC.
SELECT first_name, salary
FROM employees
ORDER BY salary DESC;
Lies das Ergebnis vom höchsten zum niedrigsten Wert: Farid 83.000, Ben 71.000, Emma 65.000, David 60.000, Hugo 58.000, Ana 52.000, Chloe 48.000 und Grace 45.000. Die Datenbank ordnet die Ergebniszeilen neu; diese Abfrage ändert die gespeicherte Tabelle nicht.
Vor dem Sortieren filtern
SELECT name, price
FROM products
WHERE category = 'Lighting'
ORDER BY price;
Nur die drei Lighting-Zeilen gelangen in dieses Ergebnis. Ihre aufsteigenden Preise ergeben Lamp Shade 15,50, Desk Lamp 24,99 und dann Floor Lamp 89,00. ORDER BY steht in der Anweisung nach WHERE. Die Umkehrung dieser Klauseln ist ein Syntaxfehler.
Die Sortierspalte muss nicht angezeigt werden. SELECT first_name FROM employees ORDER BY salary DESC; liefert dieselbe Namensreihenfolge, ohne Gehälter anzuzeigen. PostgreSQL schränkt dies bei DISTINCT ein: Eine DISTINCT-Abfrage muss ihre Sortierspalten auswählen.
Den gespeicherten Datentyp lesen
Numerische Spalten werden nach numerischer Größe sortiert. Textspalten werden nach Zeichen entsprechend ihrer Sortierfolge sortiert. Die Textwerte '10', '9' und '100' werden bei gewöhnlicher Zeichenreihenfolge als '10', '100', '9' sortiert. Das ist keine korrekte numerische Rangfolge. Prüfe daher den Spaltentyp, wenn Beträge falsch angeordnet erscheinen.
Die Beispielwerte von hire_date sind vollständige Textdatumswerte fester Länge mit dem Jahr an erster Stelle. ORDER BY hire_date beginnt mit Farid am 2017-09-12 und endet mit Grace am 2024-02-19. DESC kehrt dies um, sodass die neuesten Einstellungen zuerst kommen. Textdatumswerte mit dem Monat an erster Stelle wie MM/DD/YYYY werden zuerst nach Monat und dann nach Jahr verglichen und können über mehrere Jahre hinweg keine zuverlässige Kalenderreihenfolge ergeben.
Die Textreihenfolge hängt von der Sortierfolge ab
Die standardmäßige binäre Sortierfolge von SQLite setzt ASCII-Großbuchstaben vor Kleinbuchstaben. Nach dieser Regel steht 'Zebra' vor 'apple' und 'é' kommt nach 'z'. Viele PostgreSQL-Datenbanken verwenden sprachabhängige Sortierfolgen, die eine andere Reihenfolge ergeben. Einheitliche Groß- und Kleinschreibung hilft, aber die Vergleichsregeln der Datenbank entscheiden weiterhin über die Reihenfolge von Zeichen mit Akzenten und anderen Zeichen.
Verwende Spaltennamen für eine klare Sortierangabe. ORDER BY 2 DESC bezeichnet den zweiten Eintrag in der SELECT-Liste, sodass das Verschieben von Spalten die Sortierung stillschweigend ändern kann. ORDER BY 'salary' bezeichnet eine Textkonstante, nicht die Gehaltsspalte: SQLite liefert damit keine sinnvolle Sortierung und PostgreSQL lehnt es ab. Schreibe ORDER BY salary.
Wichtige Erkenntnisse
- ORDER BY bestimmt die Zeilenreihenfolge; ASC ist die Voreinstellung und DESC kehrt die Richtung um.
- WHERE filtert Zeilen, bevor sie sortiert werden.
- Numerische Größe, Datumsdarstellung und Textsortierfolge bestimmen, was „aufsteigend“ bedeutet.
- Benenne Sortierspalten ausdrücklich, um Konstanten in Anführungszeichen und sich ändernde Spaltenpositionen zu vermeiden.
5.2 Mehrere Sortierspalten, gleiche und fehlende Werte
Eine zweite Sortierspalte ist nur wichtig, wenn Zeilen in der ersten gleiche Werte haben. Stell dir eine sortierte Personalliste vor: Gruppiere zuerst nach Stadt und ordne dann die Namen innerhalb jeder Stadt.
Den Sortierspalten von links nach rechts folgen
SELECT last_name, city
FROM employees
ORDER BY city, last_name;
Das Ergebnis beginnt mit Kim und Okafor in Boston. Dann folgen Haddad, Lopez, Nguyen und O'Neill in Chicago. Brown und Carter in Denver stehen zuletzt. last_name konkurriert nicht mit city; der Nachname entscheidet nur innerhalb derselben Stadt über die Reihenfolge.
Eine Umkehrung der Spalten ändert die Hauptreihenfolge. ORDER BY last_name, city sortiert hauptsächlich nach Nachnamen und zieht die Stadt nur bei gleichen Nachnamen heran. Verwende eine ORDER-BY-Klausel mit Kommas zwischen den Sortierspalten. Eine zweite ORDER-BY-Klausel ist ungültig.
Jeder Spalte ihre Richtung geben
ORDER BY department, salary DESC bedeutet Abteilung aufsteigend, dann Gehalt innerhalb jeder Abteilung absteigend. DESC gehört nur zu salary. Um beide absteigend zu sortieren, schreibe department DESC, salary DESC.
Bei der standardmäßigen NULL-Sortierung von SQLite setzt die erste Form die fehlende Abteilung von Grace an den Anfang. IT folgt mit Farid und dann Ben; bei Marketing steht David vor Hugo; bei Sales folgen Emma, Ana und dann Chloe. Du liest eine Hierarchie von Vergleichen und sortierst nicht zuerst jede Zeile nach Gehalt, um diese Reihenfolge dann zu ignorieren.
Gleiche Werte mit einem eindeutigen Wert auflösen
Zeilen, die in allen Sortierspalten gleiche Werte haben, können in beliebiger Reihenfolge erscheinen. ORDER BY city legt nicht fest, welche beschäftigte Person in Chicago zuerst kommt. Eine eindeutige Sortierreihenfolge ergänzt als letzte Spalte eine, die jede Zeile eindeutig identifiziert:
SELECT first_name, city
FROM employees
ORDER BY city, employee_id;
Die IDs lösen alle gleichen Stadtwerte auf. Bei unveränderten Daten sorgt das dafür, dass ein späteres LIMIT oder eine Seite einen wiederholbaren Teil der sortierten Liste auswählt. Ein eindeutiges nachrangiges Sortierkriterium legt fest, welche Zeilen an einer Grenze erscheinen; es schließt keine zusätzlichen Zeilen mit gleichen Werten ein.
Fehlende Werte bewusst platzieren
Die Voreinstellungen der Datenbanken unterscheiden sich:
| Datenbank | NULL bei ASC | NULL bei DESC |
|---|---|---|
| SQLite, MySQL, SQL Server | Zuerst | Zuletzt |
| PostgreSQL, Oracle | Zuletzt | Zuerst |
Daher setzt die Abteilungsabfrage Grace bei den PostgreSQL-Voreinstellungen ans Ende, obwohl sie in SQLite zuerst steht. Dieser Unterschied ist unabhängig von der Sortierrichtung des Gehalts.
SELECT first_name, department, salary
FROM employees
ORDER BY department NULLS LAST, salary DESC;
SQLite ab Version 3.30, PostgreSQL und Oracle unterstützen NULLS FIRST und NULLS LAST. Hier setzen sie Grace hinter alle erfassten Abteilungen und erhalten dabei die Gehaltsreihenfolge innerhalb jeder Abteilung. MySQL und SQL Server akzeptieren diese Klauseln nicht.
Übersetze eine gewünschte Hierarchie in derselben Reihenfolge, in der sie genannt wird: „nach Abteilung, innerhalb jeder Abteilung das höchste Gehalt zuerst“ ergibt department, salary DESC. „Alphabetisch nach Nachnamen, dann nach Vornamen“ ergibt last_name, first_name. Ergänze eine ID zuletzt, wenn du bei Personen mit identischen Namen eine wiederholbare Reihenfolge brauchst.
Wichtige Erkenntnisse
- Spätere ORDER-BY-Spalten entscheiden bei gleichen Werten in vorherigen Spalten.
- ASC oder DESC gilt für die eigene Spalte; bei fehlender Richtungsangabe gilt ASC.
- Eine letzte Sortierspalte mit eindeutigen Werten macht die Reihenfolge bei unveränderten Daten eindeutig.
- Die Platzierung von NULL hängt von der Datenbank ab; unterstützte NULLS-FIRST- und NULLS-LAST-Klauseln legen sie ausdrücklich fest.
- Ein nachrangiges Sortierkriterium legt die Zeilenauswahl fest, ohne ein LIMIT um alle Zeilen mit gleichen Werten zu erweitern.
5.3 Die ersten Ergebnisse und Seiten mit LIMIT
LIMIT behält höchstens eine gewählte Anzahl von Ergebniszeilen. Es entscheidet nicht, welche Zeilen zuerst stehen sollen. Verwende ORDER BY, um einer Auswahlliste eine Bedeutung wie höchstes Gehalt, neueste oder günstigste zu geben.
Sortieren, dann begrenzen
SELECT first_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;
Die sortierten Gehälter beginnen mit Farid 83.000, Ben 71.000 und Emma 65.000, sodass diese drei Zeilen erhalten bleiben. Ohne ORDER BY gibt LIMIT 3 irgendwelche drei Zeilen zurück, ohne zu garantieren, dass sie die höchsten Gehälter enthalten.
WHERE wirkt vor der Begrenzung. WHERE city = 'Boston' ORDER BY salary DESC LIMIT 5 gibt nur David und Grace zurück, weil nur zwei Beschäftigte die Bedingung erfüllen. LIMIT ist eine Obergrenze und keine Aufforderung, zusätzliche Zeilen zu erfinden. LIMIT 0 gibt keine zurück.
Zeilen für eine spätere Seite überspringen
OFFSET überspringt Zeilen, bevor LIMIT die zurückzugebenden Zeilen zählt. ORDER BY salary DESC LIMIT 3 OFFSET 3 überspringt Farid, Ben und Emma und gibt dann David, Hugo und Ana zurück: die Positionen vier bis sechs.
Für Seite k mit n Zeilen pro Seite überspringst du (k − 1) × n Zeilen. Seite drei bei drei Zeilen pro Seite verwendet LIMIT 3 OFFSET 6. Nur Chloe und Grace bleiben übrig. Die erste Seite hat den Versatz null, nicht eins.
„Zweite Zeile“ und „zweiter unterschiedlicher Wert“ sind verschiedene Anfragen. ORDER BY salary DESC LIMIT 1 OFFSET 1 gibt hier Ben mit 71.000 zurück. Hätten zwei Beschäftigte dasselbe höchste Gehalt, würde diese Abfrage eine weitere Person mit dem höchsten Gehalt zurückgeben. Um das zweite unterschiedliche Gehalt zu finden, wähle vor dem Sortieren und Überspringen DISTINCT salary aus.
Die Auswahl an der Grenze festlegen
ORDER BY city LIMIT 3 schließt die beiden Beschäftigten aus Boston und eine Person aus Chicago ein, legt aber nicht fest, welche Person aus Chicago. ORDER BY city, employee_id LIMIT 3 wählt David, Grace und Ana aus. Die eindeutige ID legt die Auswahl an der Grenze fest.
Um alle Zeilen mit demselben letzten Sortierwert zu behalten, unterstützen PostgreSQL ab Version 13 und Oracle FETCH FIRST 3 ROWS WITH TIES. Mit ORDER BY city bleiben sechs Zeilen erhalten: beide Boston-Zeilen und alle vier Chicago-Zeilen. Enthält ORDER BY auch eine eindeutige ID, können Zeilen nicht im vollständigen Sortierschlüssel übereinstimmen.
Die Syntax der Datenbank erkennen
| Datenbank | Eine Begrenzung auf drei Zeilen |
|---|---|
| SQLite, PostgreSQL, MySQL | ORDER BY salary DESC LIMIT 3 |
| PostgreSQL, Oracle ab 12c | ORDER BY salary DESC FETCH FIRST 3 ROWS ONLY |
| SQL Server | SELECT TOP (3) first_name, salary FROM employees ORDER BY salary DESC; |
Standard-SQL verwendet OFFSET und FETCH, nicht LIMIT. PostgreSQL und Oracle akzeptieren OFFSET 3 ROWS FETCH FIRST 3 ROWS ONLY. SQL Server verwendet ORDER BY salary DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY; für diese Form der Seiteneinteilung ist ORDER BY erforderlich.
SQLite und MySQL akzeptieren auch LIMIT 6, 3, mit dem Versatz an erster Stelle. Bevorzuge LIMIT 3 OFFSET 6, damit die Rollen ausdrücklich erkennbar sind. Bei der Seiteneinteilung wird für jede Seite erneut eine Abfrage ausgeführt. Eine eindeutige Sortierreihenfolge hält die Seiten konsistent, solange die Daten unverändert bleiben; Einfügungen oder Löschungen zwischen Anfragen können trotzdem dazu führen, dass Seiten Datensätze wiederholen oder überspringen.
Wichtige Erkenntnisse
- ORDER BY entscheidet, welche Zeilen zuerst kommen; LIMIT behält höchstens die angeforderte Anzahl.
- OFFSET überspringt Zeilen, bevor LIMIT zählt; die erste Seite verwendet den Versatz null.
- Wähle zuerst DISTINCT, wenn du unterschiedliche Werte statt einzelner Zeilen in eine Rangfolge bringst.
- Ein eindeutiges nachrangiges Sortierkriterium legt die Auswahl an der Grenze fest; WITH TIES kann zusätzliche Zeilen mit gleichem vollständigem Sortierschlüssel einschließen.
- LIMIT, TOP und OFFSET/FETCH sind datenbankspezifische Formen der Zeilenbegrenzung.
- Geänderte Daten können Seitengrenzen zwischen Anfragen verschieben.
6Eine vollständige Abfrage erstellen und prüfen
Eine Frage aus dem Berufsalltag verbindet gewöhnlich mehrere Entscheidungen: welche Datensätze zählen, welche Angaben angezeigt werden und welche Zeilen zuerst kommen. Wenn du diese Entscheidungen getrennt planst, kannst du eine Abfrage schreiben, deren Teile zusammenpassen. Die geschriebene Klauselreihenfolge und die logische Reihenfolge erklären, warum ein Filter eine verborgene Spalte verwenden kann und warum eine Begrenzung für passende Zeilen gilt. Außerdem prüfst du Grenzen, fehlende Daten und gleiche Werte, bevor du einem plausibel aussehenden Ergebnis vertraust.
6.1 Geschriebene Reihenfolge und logische Verarbeitung
SQL-Klauseln haben eine feste Reihenfolge beim Schreiben. Ihre logische Reihenfolge erklärt das Ergebnis als eine Folge von Entscheidungen, selbst wenn die Datenbank einen anderen internen Ausführungsplan verwendet.
Die Anweisung in Klauselreihenfolge schreiben
SELECT DISTINCT city
FROM employees
WHERE department = 'Sales'
ORDER BY city
LIMIT 2 OFFSET 0;
SELECT und FROM bezeichnen die angeforderten Spalten und die Quelltabelle. Die anderen Klauseln sind optional, behalten aber, falls vorhanden, diese Reihenfolge bei: WHERE, ORDER BY, LIMIT und dann OFFSET in dieser LIMIT-Form. DISTINCT steht direkt nach SELECT.
Verwende eine WHERE-Klausel mit mehreren verknüpften Bedingungen. Ein zweites WHERE ist ein Syntaxfehler. Dasselbe gilt für ORDER BY: Setze mehrere Sortierspalten in eine Klausel und trenne sie durch Kommas. WHERE unter ORDER BY zu verschieben, verlangt keine andere Verarbeitungsreihenfolge, sondern erzeugt ungültiges SQL.
Die logischen Entscheidungen verfolgen
| Logischer Schritt | Was im Beispiel geschieht |
|---|---|
| FROM | Zeilen der Beschäftigten lesen. |
| WHERE | Ana, Chloe und Emma aus Sales behalten. |
| SELECT | Ihre Stadtwerte behalten: Chicago, Chicago, Denver. |
| DISTINCT | Diese Werte auf Chicago und Denver reduzieren. |
| ORDER BY | Chicago vor Denver setzen. |
| OFFSET und LIMIT | Keine Zeilen überspringen und höchstens zwei zurückgeben. |
Das Ergebnis ist Chicago, dann Denver. Die wiederholte Stadt verschwindet, bevor die Begrenzung Ergebniszeilen zählt. Es werden nicht zwei Beschäftigte genommen und dann gefragt, ob sie in unterschiedlichen Städten wohnen.
Der Optimierer kann einen anderen physischen Ausführungsplan verwenden, der dasselbe Ergebnis wie diese logische Folge erzeugt.
Spalten dort verwenden, wo sie verfügbar sind
WHERE prüft die Quellzeilen, bevor SELECT die angezeigten Spalten auswählt:
SELECT first_name
FROM employees
WHERE salary > 60000;
Das funktioniert, ohne dass das Gehalt in der Ausgabe steht. Die passenden Namen sind Ben, Emma und Farid. Bei der Prüfung ist das Gehalt weiterhin eine Spalte jeder Quellzeile.
Ebenso ist das Filtern vor dem Begrenzen für ein Spitzenergebnis innerhalb einer Gruppe entscheidend:
SELECT first_name
FROM employees
WHERE department = 'Sales'
ORDER BY salary DESC
LIMIT 1;
Die Antwort ist Emma. Zuerst werden die Beschäftigten aus Sales ausgewählt; dann werden ihre Gehälter in eine Rangfolge gebracht. Würde man zuerst die Person mit dem höchsten Gehalt im Unternehmen nehmen und diese einzelne Zeile auf Sales prüfen, verfehlte man die beabsichtigte Antwort, weil Farid zu IT gehört.
Die Struktur sichtbar machen
Schreibe eine Klausel pro Zeile und setze längere Bedingungen auf separate eingerückte Zeilen. Für „Produkte aus Furniture unter 200 Dollar, höchster Preis zuerst“ verwende:
SELECT name, price
FROM products
WHERE category = 'Furniture'
AND price < 200
ORDER BY price DESC;
Office Chair mit 149,00 kommt vor Bookshelf mit 120,00. Die beiden Bedingungen stehen in einem gemeinsamen WHERE, der numerische Schwellenwert hat kein Währungszeichen und ORDER BY sortiert die passenden Zeilen. Wenn du jede Zeile anhand ihrer Aufgabe prüfst, lassen sich sowohl Syntaxfehler als auch falsche Interpretationen leichter finden.
Wichtige Erkenntnisse
- Schreibe SELECT, FROM, WHERE, ORDER BY und LIMIT in der vorgeschriebenen Klauselreihenfolge.
- Lies logisch zuerst die Tabelle, filtere, wähle Spalten, entferne Duplikate, sortiere und begrenze dann die Zeilen.
- WHERE kann Quellspalten prüfen, die SELECT nicht anzeigt.
- Das Filtern vor der Rangbildung findet das Spitzenergebnis innerhalb der angeforderten Gruppe.
6.2 Von einer Anfrage zur geprüften Antwort
Bevor du SQL schreibst, bestimme die einzelnen Entscheidungen, die in einer alltäglichen Anfrage stecken. Jede Entscheidung gehört zu einer Klausel, und jede Klausel lässt sich anhand der beabsichtigten Antwort prüfen.
Sechs Entscheidungen treffen
- Welche Tabelle enthält die Datensätze? Wähle FROM.
- Welche Datensätze passen? Erstelle WHERE.
- Welche Felder beantworten die Frage? Wähle SELECT.
- Sind wiederholte Ergebniswerte nützlich? Entscheide über DISTINCT.
- Was soll zuerst kommen? Erstelle ORDER BY.
- Gibt es eine Obergrenze oder eine Seite? Ergänze LIMIT und OFFSET.
Bei „mindestens“ schließe Gleichheit ein. „Einer von“ deutet auf IN hin, „enthält“ auf ein LIKE-Muster mit Prozentzeichen an beiden Enden, „fehlend“ auf IS NULL und „unterschiedliche Werte“ auf DISTINCT. Eine Anfrage nach den ersten n Zeilen braucht sowohl eine Sortierrichtung als auch eine Begrenzung.
Eine Personalauswahl erstellen
„Zeige die Namen und Einstellungsdaten der drei zuletzt eingestellten Beschäftigten außerhalb von Sales, für die eine Telefonnummer hinterlegt ist, mit den neuesten zuerst.“ Schließe Beschäftigte ohne zugewiesene Abteilung in die Bedeutung von außerhalb von Sales in dieser Anfrage ein.
Beginne mit employees. Die passende Abteilungsregel lautet department <> 'Sales' OR department IS NULL. Gruppiere diese Auswahl, damit die Telefonregel für beide Zweige gilt. Zeige Namen und Daten an und bringe dann die passenden Zeilen in eine Rangfolge:
SELECT first_name, last_name, hire_date
FROM employees
WHERE (department <> 'Sales' OR department IS NULL)
AND phone IS NOT NULL
ORDER BY hire_date DESC
LIMIT 3;
Grace Okafor vom 2024-02-19 steht zuerst, David Kim vom 2020-11-23 an zweiter und Farid Haddad vom 2017-09-12 an dritter Stelle. Entfernst du den IS-NULL-Zweig, fällt Grace heraus und nur zwei Ergebnisse bleiben. Kläre bei einer unklaren Anfrage, wie fehlende Abteilungen zählen sollen, und nenne die Entscheidung bei der Antwort.
Kategorie, Preis und Lagerbestand kombinieren
„Welche Produkte aus Lighting oder Storage kosten weniger als 20 Dollar und sind vorrätig, die günstigsten zuerst?“ Verwende IN für die beiden Kategorieoptionen und verlange eine bekannte positive Stückzahl:
SELECT name, price
FROM products
WHERE category IN ('Lighting', 'Storage')
AND price < 20
AND stock > 0
ORDER BY price;
Paper Tray mit 9,99 kommt vor Desk Organizer mit 18,75. Lamp Shade ist günstig genug und gehört zu einer ausgewählten Kategorie, sein Lagerbestand ist aber null, sodass es die letzte Prüfung nicht besteht. Auch eine fehlende Lagerstückzahl würde die Prüfung nicht bestehen, weil sie nicht belegen kann, dass der Lagerbestand positiv ist.
Die Zeilen prüfen, die einen Fehler aufdecken könnten
Beginne mit SELECT * FROM products LIMIT 5;, wenn du das Schema und einige Datensätze erkundest. Füge Filter einzeln hinzu, prüfe Änderungen der Ergebnisanzahl und zeige geprüfte Spalten vorübergehend an, wenn es hilfreich ist.
Prüfe genaue Grenzen, fehlende Werte, die Groß- und Kleinschreibung von Text und gleiche Werte an der Grenze. NOT zeigt Zeilen, bei denen eine Bedingung falsch war; es zeigt keine Zeilen, bei denen die Bedingung unbekannt war. Führe IS-NULL-Prüfungen gesondert aus. Prüfe, ob deine Ausgabe die angeforderten Spalten enthält und ob ORDER BY gleiche Werte auflöst, die die Antwort beeinflussen.
Prüfe beim Übertragen der Abfrage in eine andere Datenbank die Syntax für Zeilenbegrenzungen, die Regeln zur Groß- und Kleinschreibung bei Gleichheit und LIKE, Anführungszeichen für Bezeichner, die Behandlung von Datumswerten und die Platzierung von NULL. Die Beispiele verwenden LIMIT in SQLite und PostgreSQL; die Form für Zeilenbegrenzungen in Standard-SQL ist OFFSET mit FETCH FIRST.
Wichtige Erkenntnisse
- Plane Tabelle, passende Zeilen, Ausgabespalten, Duplikate, Reihenfolge und Zeilenanzahl getrennt.
- Schreibe die Entscheidung zu fehlenden Werten ausdrücklich auf, wenn ein Ausschluss Datensätze ohne Zuweisung einschließen soll.
- Prüfe Grenzen und die Auswirkungen einzelner Filter anhand der Frage.
- Untersuche NULL-Werte gesondert, weil NOT unbekannt nicht in wahr umwandelt.
- Prüfe beim Wechsel der Datenbank erneut Groß- und Kleinschreibung, Datumswerte, Namen, NULL-Sortierung und Zeilenbegrenzungen.
Abfragen mit SELECT: Beispiele
1Von Beschäftigtendaten zu einer Städteliste
11 Schritte
- 1EinführungEine Tabelle, zwei Arten von Antworten
Eine Personalliste und eine Liste der Städte, in denen Beschäftigte wohnen, verwenden dieselben Beschäftigtendatensätze, brauchen aber unterschiedliche Ergebnisformen. Ein einfaches SELECT wählt die anzuzeigenden Felder aus. DISTINCT kann dann wiederholte ausgewählte Werte reduzieren. Wir erstellen zuerst ein zweispaltiges Ergebnis für Beschäftigte, ändern dann die Frage zu unterschiedlichen Städten und verfolgen, was verschwindet.
- 2ErklärungDie angezeigten Spalten auswählen
Beginne mit einer konkreten Anfrage: Zeige für jede beschäftigte Person die Stadt, gefolgt vom Vornamen. Schreibe:
SELECT city, first_name FROM employees;Die SELECT-Liste legt die Reihenfolge der Ausgabespalten fest, sodass die Stadt zuerst kommt. FROM liefert die Tabelle. Es gibt keinen Filter, daher tragen alle acht Beschäftigten eine Zeile bei; diese einfache Abfrage lässt die gespeicherten Datensätze unverändert.
- 3BeispielDen Aufbau des Ergebnisses lesen
Der Datensatz von Ana steuert Chicago und Ana bei; der von Ben Denver und Ben. Alle übrigen Beschäftigten steuern dieselben zwei Felder bei. Das Ergebnis hat daher acht Zeilen und zwei Spalten. Wiederholte Städte bleiben erhalten, weil diese Zeilen weiterhin unterschiedliche Personen beschreiben. Es gibt kein ORDER BY, daher benennen diese Beispiele Zeilen, ohne ihre Anzeigereihenfolge zu garantieren.
- 4HerausforderungEine geänderte SELECT-Liste prüfen
Was ändert sich, wenn die Abfrage zu
SELECT first_name FROM employees;wird? Gib ihre Zeilen- und Spaltenanzahl an.---reveal---
Sie gibt weiterhin acht Zeilen zurück, jetzt mit einer Spalte, first_name. Das Entfernen von city aus SELECT entfernt ein angezeigtes Feld, keine Beschäftigtendatensätze. Um die Zeilen zu reduzieren, wäre ein Filter oder eine Zeilenbegrenzung nötig.
- 5TippSyntaxfehler eingrenzen
Trenne Spaltennamen durch Kommas, lasse aber ein abschließendes Komma vor FROM weg. Beende die Anweisung mit einem Semikolon;
--beginnt einen Kommentar bis zum Zeilenende. Meldet die Datenbank eine unbekannte Spalte, vergleiche die Schreibweise mit dem Schema.SELECT *ist für einen ersten Blick nützlich, während ausdrückliche Namen ein gespeichertes Ergebnis auf das Nötige beschränken. - 6ErklärungNach unterschiedlichen Städten fragen
Frage nun, in welchen Städten Beschäftigte wohnen. Vornamen gehören nicht mehr zu dieser Antwort:
SELECT DISTINCT city FROM employees;Die acht Stadteinträge reduzieren sich auf Chicago, Denver und Boston, ohne garantierte Reihenfolge. DISTINCT entfernt Wiederholungen aus dem ausgewählten Ergebnis, nicht aus der gespeicherten Beschäftigtentabelle. Jede Stadt erscheint einmal, auch wenn mehrere Personen dort wohnen.
- 7BeispielVollständige ausgewählte Zeilen vergleichen
Füge die Abteilung zur SELECT-Liste hinzu. Ana und Chloe steuern beide das Paar Sales-Chicago bei, das zu einer Zeile zusammengefasst wird. Emma steuert Sales-Denver bei, das erhalten bleibt, weil die Stadt anders ist. Das vollständige Ergebnis von
SELECT DISTINCT department, city FROM employees;hat sieben Zeilen. DISTINCT wird einmal nach SELECT geschrieben und vergleicht alle ausgewählten Felder zusammen. - 8HerausforderungEine eindeutige ID verändert das Entfernen von Duplikaten
Wie viele Zeilen würde
SELECT DISTINCT employee_id, city FROM employees;zurückgeben und warum?---reveal---
Alle acht Zeilen bleiben erhalten. Jede employee_id ist eindeutig, sodass sich jedes ID-Stadt-Paar von allen anderen Paaren unterscheidet. Wiederholte Städte allein reichen nicht aus, um vollständige ausgewählte Zeilen zu Duplikaten zu machen.
- 9KernaussageDeuten, was eine NULL-Zeile aussagt
Eine DISTINCT-Abteilungsliste enthält Sales, IT, Marketing und eine NULL-Zeile für Grace. Auch wiederholte Kennzeichnungen fehlender Werte würden zu einer zusammengefasst. Diese Zeile sagt, dass eine Abteilung nicht erfasst ist; sie ist keine weitere benannte Abteilung. Bei der Duplikatgruppierung werden NULL-Werte zusammen behandelt, obwohl ein gewöhnlicher Vergleich
NULL = NULLunbekannt ist. - 10HerausforderungMit einer sortierten Auswahlliste abschließen
Sage das Ergebnis von
SELECT DISTINCT city FROM employees ORDER BY city LIMIT 2;voraus. Gib die Werte in ihrer zurückgegebenen Reihenfolge an und erkläre, was die Begrenzung zählt.---reveal---
Boston, dann Chicago. DISTINCT reduziert die Stadtwerte zuerst auf drei; ORDER BY sortiert diese Werte und LIMIT behält zwei. Es zählt unterschiedliche Ergebnisstädte nach dem Entfernen der Duplikate, nicht zwei Beschäftigtendatensätze.
- 11ZusammenfassungDie Ausgabe auf die Frage abstimmen
Ein Personalergebnis behält identifizierende Felder; eine Städteliste wählt mit DISTINCT nur die Stadt aus. Die ausgewählten Spalten bestimmen die Duplikatvergleiche, während ORDER BY die Zeilenreihenfolge bestimmt. Prüfe beim Ändern einer Abfrage sowohl die Ausgabefelder als auch, was eine Ergebniszeile darstellt.
2Einen Filter mit der beabsichtigten Bedeutung erstellen
13 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungJeder Filter stellt eine genaue Frage
- 2ErklärungDen Gehaltsschwellenwert übersetzen
- 3HerausforderungDie Grenze bei Bedarf einschließen
- 4TippNumerische Literale einfach schreiben
- 5ErklärungEinen Textwert in Anführungszeichen setzen
- 6BeispielEinen Apostroph innerhalb des Werts erhalten
- 7ErklärungEine vollständige Datumsgrenze verwenden
- 8HerausforderungEin Datum mit Uhrzeit prüfen
- 9ErklärungDie Bedingungen verknüpfen
- 10BeispielEine Stadtregel auf Alternativen anwenden
- 11HerausforderungDie Gruppe umkehren
- 12HerausforderungEin Datum und eine Abteilungsgruppe kombinieren
- 13ZusammenfassungEine aufschlussreiche Zeile verfolgen
3Eine genaue Liste, einen Bereich oder ein Muster wählen
15 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDrei Bedeutungen einer Übereinstimmung
- 2ErklärungMit vollständigen Kategorieoptionen beginnen
- 3BeispielEine Lagerregel auf die Liste anwenden
- 4HerausforderungEinen Ausschluss vorhersagen
- 5ErklärungEinen Preis in einen Bereich einordnen
- 6HerausforderungDie Bereichsgrenzen bewusst ausschließen
- 7TippEinen ganzen Monat mit Uhrzeiten abdecken
- 8ErklärungFestlegen, wo der Textteil stehen darf
- 9BeispielEin Zeichen mit einem Unterstrich erfassen
- 10BeispielNach dem tatsächlichen Platzhalterzeichen suchen
- 11HerausforderungEin Muster an seinen Rändern prüfen
- 12VerbindungDie Behandlung der Groß- und Kleinschreibung in der Datenbank prüfen
- 13HerausforderungEine fehlende Telefonnummer berücksichtigen
- 14HerausforderungAlle drei Arten des Abgleichs kombinieren
- 15ZusammenfassungDie Form anhand der Bedeutung wählen
4Fehlende Daten finden und beurteilen
10 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEine nicht erfasste Stückzahl bleibt ungeklärt
- 2BeispielNull von fehlenden Werten unterscheiden
- 3ErklärungDas Vorhandensein direkt prüfen
- 4HerausforderungLeere Zeichenketten prüfen
- 5ErklärungEinen Vergleich und sein Gegenteil verfolgen
- 6BeispielEinen wahren OR-Zweig entscheiden lassen
- 7HerausforderungEin falscher AND-Zweig kann entscheiden
- 8KernaussageNULL innerhalb einer Ausschlussliste vermeiden
- 9HerausforderungFehlende Abteilungen einschließen, Telefonnummern verlangen
- 10ZusammenfassungFehlende Daten gesondert untersuchen
5Eine wiederholbare sortierte Seite erstellen
15 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEine Seite ist ein Ausschnitt einer sortierten Antwort
- 2BeispielDen höchsten Wert zuerst wählen
- 3HerausforderungNur passende Produkte sortieren
- 4TippErkennen, ob numerisch sortiert wird
- 5ErklärungSortierprioritäten von links lesen
- 6HerausforderungJeder Sortierspalte ihre Richtung geben
- 7ErklärungDie verbleibenden gleichen Werte auflösen
- 8VerbindungFehlende Werte ausdrücklich platzieren
- 9BeispielDie ersten drei Zeilen der Rangfolge behalten
- 10BeispielÜber die erste Seite hinausgehen
- 11KernaussageDer Rang einer Zeile ist nicht der Rang eines unterschiedlichen Werts
- 12HerausforderungGleiche Werte an einer Grenze untersuchen
- 13TippEine andere Form der Zeilenbegrenzung erkennen
- 14HerausforderungDie zweite Stadtseite behalten
- 15ZusammenfassungDie Rangfolge vor dem Ausschnitt festlegen
6Eine Anfrage aus dem Berufsalltag übersetzen und prüfen
12 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDie Entscheidungen einer Anfrage trennen
- 2ErklärungEine gültige Klauselreihenfolge schreiben
- 3BeispielDas logische Modell verfolgen
- 4HerausforderungVor der Auswahl des Spitzenwerts filtern
- 5ErklärungDie Personalanfrage bestimmen
- 6BeispielDie Abteilungsregel ausdrücklich formulieren
- 7BeispielDie Telefonanforderung anwenden
- 8BeispielDie passenden Datensätze in eine Rangfolge bringen
- 9HerausforderungDie Entscheidung zu fehlenden Werten prüfen
- 10HerausforderungDie Klauseln zu einem Ablauf verbinden
- 11TippPrüfungen wählen, die Fehler aufdecken
- 12ZusammenfassungDie Antwort mit der Anfrage abgleichen
Abfragen mit SELECT: Übungsaufgaben
Set 1: Spalten, Vergleiche und klare Bedingungen10 Übungsfragen
Frage 1 von 10
rooms hat 12 Zeilen. Welche Form hat das Ergebnis von SELECT floor, room_name FROM rooms;?Antwort zeigenAntwort ausblenden
Frage 2 von 10
parcels speichert weight_kg als Zahl. Welche Bedingung behält Pakete mit einem Gewicht von höchstens 8 Kilogramm?Antwort zeigenAntwort ausblenden
Frage 3 von 10
D'Arcy in einer Spalte surname zu?Antwort zeigenAntwort ausblenden
Frage 4 von 10
tickets hat status und eine numerische priority. Welche Bedingung wählt offene oder ausstehende Tickets mit jeweils einer Priorität von mindestens 4 aus?Antwort zeigenAntwort ausblenden
Frage 5 von 10
visits enthält die Paare (site, day) ('East', 'Mon'), ('East', 'Mon'), ('East', 'Tue') und ('West', 'Mon'). Wie viele Zeilen gibt SELECT DISTINCT site, day FROM visits; zurück?Antwort zeigenAntwort ausblenden
Frage 6 von 10
team = 'Blue', city = 'Austin' und score = 62. Erfüllt sie WHERE team = 'Blue' OR city = 'Miami' AND score >= 80 und warum?Antwort zeigenAntwort ausblenden
Frage 7 von 10
YYYY-MM-DD. Welche Bedingung wählt Datumswerte nach dem Kalenderjahr 2025 aus?Antwort zeigenAntwort ausblenden
Frage 8 von 10
zone-Wert entweder North oder West ist?Antwort zeigenAntwort ausblenden
Frage 9 von 10
loans hat die numerischen days_late-Werte 0, 2, 5 und NULL. Wie viele Zeilen erfüllen WHERE days_late <> 0?Antwort zeigenAntwort ausblenden
Frage 10 von 10
stockrooms hat die Zeilen (room_id, building) (1, 'C'), (2, 'A'), (3, 'A'), (4, 'B'), (5, 'C'). Welche sortierten Werte ergeben sich aus SELECT DISTINCT building FROM stockrooms ORDER BY building DESC LIMIT 2;?Antwort zeigenAntwort ausblenden
Set 2: Listen, Bereiche und Zeichenmuster10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
fee hat die Werte 12, 18, 24 und 30. Welche Werte erfüllen WHERE fee BETWEEN 18 AND 30?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
report endet?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
requests hat die Zeilen (request_id, region) (31, 'South'), (32, 'East'), (33, 'South'). Welche Menge von IDs erfüllt WHERE region IN ('South', 'South')?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
labels passt zu label LIKE '__7%': 'AB7', 'A7', 'AB70' und 'ABC7'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
temperature enthält 4, 9, 14, 19 und NULL. Welche Werte erfüllen WHERE temperature NOT BETWEEN 9 AND 14?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
promo_code enthält 'VIP_2', 'VIPA2', 'VIP_' und 'VIP2'. Welche Menge passt zu WHERE promo_code LIKE 'VIP!_%' ESCAPE '!'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
appointments speichert Text mit Uhrzeiten in der Form YYYY-MM-DD HH:MM:SS mit fester Länge. Welche Bedingung wählt jeden Termin im Februar 2028 aus?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
'Maple', 'map', 'roadmap' und 'MAPS' passt beim standardmäßigen LIKE-Verhalten von SQLite zu word LIKE 'map%'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
members hat die Zeilen (member_id, tier) (41, 'Gold'), (42, 'Silver'), (43, NULL). Welche Menge von IDs erfüllt WHERE tier IN ('Silver', NULL)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
shipments erfasst einen port pro Zeile. Welche Bedingung schließt sowohl Oakland als auch Tacoma aus, wenn alle Hafenwerte erfasst sind?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 3: Fehlende Werte und kombinierte Filter10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
contacts speichert die phone-Werte NULL, '', 'NULL' und '555-0188'. Wie viele Zeilen erfüllen WHERE phone IS NULL?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
devices hat battery_pct = NULL und status = 'ready'. Was geschieht bei WHERE battery_pct > 50 OR status = 'ready'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
email-Wert, einschließlich einer leeren Zeichenkette, wenn diese in PostgreSQL als Wert gespeichert ist?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
jobs enthält die Zeilen (job_id, hours, urgent) (51, NULL, 'yes'), (52, 6, 'no'), (53, 2, 'yes'), (54, NULL, 'no'). Welche Menge erfüllt WHERE NOT (hours > 4) OR urgent = 'yes'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
files hat die folder-Werte 'Archive', 'Active' und NULL. Welche Bedingung schließt Active und den fehlenden Ordner ein, während sie Archive ausschließt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
routes hat die Zeilen (route_id, depot) (61, 'A'), (62, 'B'), (63, NULL). Welche Menge von IDs erfüllt WHERE depot NOT IN ('A', NULL) OR depot IS NULL?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
load-Werte: 0, 3, 7, NULL, NULL. Zwei Abfragen verwenden WHERE load > 3 und WHERE NOT (load > 3). Wie viele Zeilen geben sie in dieser Reihenfolge zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
deliveries hat die district-Werte 'Hill', NULL, 'Hill', NULL und 'Lake'. Wie viele Zeilen gibt SELECT DISTINCT district FROM deliveries; zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
WHERE rating >= 4 und prüft dann ausgeschlossene Zeilen mit WHERE NOT (rating >= 4). Manche Datensätze erscheinen in keinem der beiden Ergebnisse. Welche zusätzliche Prüfung zeigt Datensätze, deren Bewertung nicht erfasst wurde?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
messages hat die Betreffzeilen 'Note A', 'Alert', NULL und 'Note B'. Wie viele Zeilen erfüllen WHERE subject NOT LIKE 'Note%'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 4: Rangfolgen, gleiche Werte und spätere Seiten10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
duration_minutes hat die Werte 16, 4 und 23. In welcher Reihenfolge stehen sie bei ORDER BY duration_minutes?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
racers hat die Zeilen (racer_id, group_name, points) (71, 'A', 8), (72, 'B', 12), (73, 'A', 15). Welche ID-Reihenfolge ergibt sich aus ORDER BY group_name, points DESC?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
orders hat eindeutige order_id-Werte und mehrere Zeilen stimmen sowohl in order_date als auch in total überein. Welches ORDER BY liefert neueste Datumswerte zuerst, höchste Summen innerhalb eines Datums und eine eindeutige Reihenfolge?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
offers hat die Zeilen (offer_id, rate) (81, 40), (82, 40), (83, 35), (84, 30). Welcher Wert ergibt sich aus SELECT DISTINCT rate FROM offers ORDER BY rate DESC LIMIT 1 OFFSET 1;?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
queues enthält die Namen 'Delta', NULL und 'Alpha'. Wo steht die NULL-Zeile beim standardmäßigen ORDER BY queue_name ASC in SQLite und PostgreSQL?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
sales hat die Zeilen (sale_id, amount) (91, 70), (92, 70), (93, 55), (94, 55), (95, 20). Wie viele Zeilen gibt SELECT sale_id, amount FROM sales ORDER BY amount DESC FETCH FIRST 3 ROWS WITH TIES; in PostgreSQL zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
'6', '12' und '100'. Wie lautet ihre aufsteigende Reihenfolge?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
ORDER BY item_id LIMIT 4 OFFSET 4 auf unveränderten Zeilen mit eindeutigen IDs von 1 bis 12. Vor der nächsten Seitenabfrage wird Zeile 2 gelöscht. Welche IDs gibt LIMIT 4 OFFSET 8 nun bei derselben Sortierung zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
tasks hat die Zeilen (task_id, owner, hours) (101, 'Lee', 9), (102, 'Ari', 8), (103, 'Lee', 5), (104, 'Lee', 3). Welche ID ergibt sich aus SELECT task_id FROM tasks WHERE owner = 'Lee' ORDER BY hours DESC LIMIT 1 OFFSET 1;?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 5: Vollständige Abfragen und Ergebnisprüfungen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
courses hat title, einen numerischen Wert fee und einen numerischen Wert places_left. Welche Abfrage zeigt Titel und Gebühren von Kursen unter 75 Dollar mit verfügbaren Plätzen, die günstigsten zuerst?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
cases hat die Zeilen (case_id, team, opened_on, phone) (111, 'Red', '2026-06-12', 'x'), (112, NULL, '2026-06-20', 'y'), (113, 'Blue', '2026-06-18', NULL), (114, 'Blue', '2026-06-10', 'z'). Welche sortierten IDs ergeben die zwei neuesten Fälle außerhalb von Red mit erfasster Telefonnummer, einschließlich Fällen ohne zugewiesenes Team?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
rentals hat branch = 'East' und returned = 'yes'. Eine Abfrage soll nicht zurückgegebene Ausleihen aus East oder West anzeigen, aber diese Zeile erscheint. Der Filter lautet branch = 'East' OR branch = 'West' AND returned = 'no'. Welche Korrektur wendet die Rückgaberegel auf beide Filialen an?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
catalog hat ASCII-Produktnamen. Welche Bedingung findet in SQLite und PostgreSQL Namen, die steel enthalten, ohne Unterschiede in der Groß- und Kleinschreibung von ASCII-Buchstaben zu beachten?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
'G', 'G1', 'H2', 'J' und 'J1'. Welche Menge erfüllt WHERE code BETWEEN 'G' AND 'J' AND code NOT LIKE 'H%'?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
logs enthält die Zeilen (region, channel) ('East', 'web'), ('East', 'web'), ('East', 'store'), ('West', 'web'), ('West', 'store'). Welche sortierten Zeilen ergeben sich aus SELECT DISTINCT region, channel FROM logs WHERE channel = 'web' ORDER BY region DESC LIMIT 1;?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
bids die Zeilen (bid_id, amount) (121, 90), (122, 90), (123, 80), (124, 80). Wie viele Zeilen gibt SELECT bid_id, amount FROM bids ORDER BY amount DESC, bid_id FETCH FIRST 3 ROWS WITH TIES; zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
sensors enthält die Zeilen (sensor_id, reading, enabled) (131, NULL, 'yes'), (132, 8, 'yes'), (133, 2, 'no'), (134, NULL, 'no'). Welche Menge erfüllt WHERE NOT (reading > 5 AND enabled = 'yes')?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
fee > 50 und die einzigen verfügbaren Testdatensätze haben Gebühren von 20 und 80. Welche zusätzliche Testgebühr deckt den Fehler am unmittelbarsten auf?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
Abfrage
SELECT first_name FROM employees; fragt bei der Datenbank das Vornamensfeld jeder beschäftigten Person ab.Abfrageoptimierer
AND
ASC
price ASC setzt das günstigste Beleuchtungsprodukt an die erste und das teuerste an die letzte Stelle.ausgewählte Wertekombination
B
Bereichsgrenze
BETWEEN 15.50 AND 89.00 ist eingeschlossen, sodass Produkte mit genau 15,50 oder 89,00 beide die Bedingung erfüllen.BETWEEN
price BETWEEN 15.50 AND 89.00 schließt Produkte mit einem Preis von genau 15,50 oder 89,00 ein, den beiden genannten Bereichsgrenzen.Bezeichner
hire_date benennt eine Spalte, während der Text '2024-02-19' in Anführungszeichen einen Wert darstellt.D
DATE-Typ
DATE '2022-01-01'; SQLite verwendet diese Syntax für typisierte Literale nicht.DESC
ORDER BY hire_date DESC setzt in der Beschäftigtenliste eine 2024 eingestellte Person vor eine 2023 eingestellte Person.DISTINCT
SELECT DISTINCT city FROM employees; nur diese drei Städte auf.doppelte Ergebniszeile
dreiwertige Logik
price > 100 wahr ist.E
eindeutige Sortierreihenfolge
ORDER BY city, employee_id legt die Position jeder beschäftigten Person durch die eindeutige ID fest.einschließender Schwellenwert
salary >= 60000 verwendet.Ergebnismenge
SELECT city FROM employees; acht Zeilen, wobei wiederholte Stadtwerte erlaubt sind.Ergebnisprüfung
ESCAPE-Klausel
LIKE 'SPRING!_%' ESCAPE '!' macht den Unterstrich nach SPRING zu einem tatsächlichen Zeichen.F
FROM-Klausel
SELECT name, price FROM products; bezeichnet products als Quelle beider Felder.G
Grenzwertprüfung
H
halboffener Datumsbereich
'2024-04-01' und behält dadurch späte Uhrzeiten am letzten Tag.I
ILIKE
name ILIKE '%desk%' kann Produktnamen finden, die den großgeschriebenen Text Desk enthalten.IN
department IN ('IT', 'Marketing') wählt alle Beschäftigten aus IT oder Marketing aus, ohne einen Abteilungsvergleich zu wiederholen.IN-Liste
(6, 2, 2, 4) trifft trotz ihrer Reihenfolge und Wiederholung auf dieselben Beschäftigtendatensätze zu wie (2, 4, 6).IS NOT DISTINCT FROM
IS NOT NULL
phone IS NOT NULL behält eine beschäftigte Person mit erfasster Telefonnummer, auch wenn deren Abteilung fehlt.IS NULL
phone IS NULL findet die Beschäftigten, in deren Datensätzen kein Telefonwert erfasst ist.ISO-Datumsformat
hire_date >= '2023-01-01' bei Vergleichen in Kalenderreihenfolge Beschäftigte ein, die an oder nach diesem Datum eingestellt wurden.K
Klauselreihenfolge
L
leere Zeichenkette
phone = '' auf eine leere Zeichenkette und findet keine fehlenden Telefonwerte von Beschäftigten.LIKE
name LIKE '%Lamp%' findet jeden Produktnamen, der Lamp enthält, unabhängig davon, ob Lamp am Anfang, in der Mitte oder am Ende steht.LIMIT
logische Verarbeitungsreihenfolge
N
nachrangiges Sortierkriterium
NOT
stock > 10 schließt ein Produkt mit fehlendem Lagerbestand nicht ein, weil die Bedingung für diese Zeile weiterhin unbekannt ergibt.NOT BETWEEN
stock NOT BETWEEN 5 AND 40 behält ein Produkt mit Lagerbestand null und eines mit sechzig, schließt aber fehlende Lagerbestände aus.NOT IN
city NOT IN ('Chicago', 'Denver') behält Beschäftigte in Boston, weil sich ihre Städte von beiden Einträgen unterscheiden.NULL
NULLS LAST
department NULLS LAST setzt in aktuellen SQLite- und PostgreSQL-Abfragen Beschäftigte ohne erfasste Abteilung hinter die erfassten Abteilungen.numerisches Literal
20.50 in price < 20.50 hat weder Anführungszeichen noch Tausendertrennzeichen oder Währungszeichen.O
OFFSET
Operatorrangfolge
OR
ORDER BY
ORDER BY salary DESC setzt die Person mit dem höchsten Gehalt an die erste Stelle, ohne einen gespeicherten Beschäftigtendatensatz zu ändern.P
primäre Sortierspalte
ORDER BY city, last_name und hält die Namen aus Boston vor denen aus Chicago.Prozent-Platzhalter
'Lamp%' erlaubt ein beliebiges Ende nach Lamp, einschließlich keines Endes beim Wert Lamp.S
schrittweiser Abfrageaufbau
Seite
SELECT-Klausel
SELECT city, first_name FROM employees; setzt die Stadt vor den Vornamen der beschäftigten Person.Sortierfolge
'Chicago' von 'chicago', sodass ein Filter für 'chicago' Zeilen mit gespeichertem Chicago nicht findet.Sortierspalte
SQL-Dialekt
SQL-Kommentar
-- kann erklären, warum ein Filter Beschäftigte ohne Zuweisung einschließt, ohne seine Bedingungen zu ändern.T
Textliteral
'O''Neill' passt zum Nachnamen O’Neill, weil seine zwei aufeinanderfolgenden einfachen Anführungszeichen für einen Apostroph stehen.TOP
SELECT TOP (3) kann eine mit LIMIT auf drei Zeilen begrenzte Auswahlliste ersetzen, wenn die Abfrage für SQL Server geschrieben wird.U
unbekannter Wahrheitswert
stock > 10 einen unbekannten Wahrheitswert, sodass die Zeile den Filter nicht passiert.Untergrenze
price BETWEEN 89.00 AND 15.50 liegt über der Obergrenze, sodass keine Treffer bleiben.Unterstrich-Platzhalter
V
Vergleichsoperator
>= schließt bei salary >= 60000 eine Person mit genau 60.000 Gehalt ein, weil dieses Gehalt dem Schwellenwert entspricht.W
WHERE-Klausel
WHERE salary < 50000 behält Beschäftigte mit einem Gehalt unter 50.000, auch wenn die Ausgabe ihre Gehälter nicht anzeigt.WITH TIES
Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.