Kapitel 1. Aufzeichnungen abrufen
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Dieses Kapitel konzentriert sich auf die grundlegenden SELECT-Anweisungen. Es ist wichtig, ein solides Verständnis der Grundlagen zu haben, da viele der hier behandelten Themen nicht nur in schwierigeren Rezepten vorkommen, sondern auch im alltäglichen SQL zu finden sind.
1.1 Alle Zeilen und Spalten aus einer Tabelle abrufen
Diskussion
Das Zeichen * hat in SQL eine besondere Bedeutung. Wenn du es verwendest, wird jede Spalte der angegebenen Tabelle zurückgegeben. Da keine WHERE-Klausel angegeben ist, wird auch jede Zeile zurückgegeben. Die Alternative wäre, jede Spalte einzeln aufzulisten:
select empno,ename,job,sal,mgr,hiredate,comm,deptno from emp
Bei Ad-hoc-Abfragen, die du interaktiv ausführst, ist es einfacher, SELECT * zu verwenden. Wenn du jedoch Programmcode schreibst, ist es besser, jede Spalte einzeln anzugeben. Die Leistung ist dieselbe, aber durch die explizite Angabe weißt du immer, welche Spalten du von der Abfrage zurückgibst. Außerdem sind solche Abfragen für andere Personen leichter zu verstehen (die möglicherweise nicht alle Spalten der Tabellen in der Abfrage kennen). Probleme mit SELECT * können auch auftreten, wenn deine Abfrage im Code enthalten ist und das Programm eine andere Menge von Spalten aus der Abfrage erhält als erwartet. Wenn du alle Spalten angibst und eine oder mehrere fehlen, ist es zumindest wahrscheinlicher, dass ein Fehler auf die fehlende(n) Spalte(n) zurückgeführt werden kann.
1.2 Abrufen einer Teilmenge von Zeilen aus einer Tabelle
Diskussion
Mit der WHERE-Klausel kannst du nur die Zeilen abrufen, an denen du interessiert bist. Wenn der Ausdruck in der WHERE-Klausel für eine beliebige Zeile wahr ist, wird diese Zeile zurückgegeben.
Die meisten Anbieter unterstützen gängige Operatoren wie =, <, >, <=, >=, ! und <>. Außerdem möchtest du vielleicht Zeilen haben, die mehrere Bedingungen erfüllen. Das kannst du erreichen, indem du AND, OR und Klammern angibst, wie im nächsten Rezept gezeigt.
1.3 Suche nach Zeilen, die mehrere Bedingungen erfüllen
Lösung
Verwende die WHERE-Klausel zusammen mit den OR- und AND-Klauseln. Wenn du z.B. alle Mitarbeiter in Abteilung 10, alle Mitarbeiter, die eine Provision verdienen, und alle Mitarbeiter in Abteilung 20, die höchstens 2.000 $ verdienen, finden möchtest:
1 select * 2 from emp 3 where deptno = 10 4 or comm is not null 5 or sal <= 2000 and deptno=20
Diskussion
Du kannst eine Kombination aus AND, OR und Klammern verwenden, um Zeilen zurückzugeben, die mehrere Bedingungen erfüllen. Im Lösungsbeispiel findet die WHERE-Klausel solche Zeilen, die:
-
Die DEPTNO ist 10
-
Der COMM ist nicht NULL
-
Das Gehalt eines Angestellten in DEPTNO 20 beträgt 2.000 $ oder weniger.
Das Vorhandensein von Klammern bewirkt, dass die Bedingungen innerhalb der Klammern gemeinsam ausgewertet werden.
Sieh dir zum Beispiel an, wie sich die Ergebnismenge ändert, wenn die Abfrage wie hier gezeigt mit Klammern geschrieben wurde:
select * from emp where ( deptno = 10 or comm is not null or sal <= 2000 ) and deptno=20 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ------ ----- ----- ----------- ----- ---------- ------ 7369 SMITH CLERK 7902 17-DEC-1980 800 20 7876 ADAMS CLERK 7788 12-JAN-1983 1100 20
1.4 Abrufen einer Teilmenge von Spalten aus einer Tabelle
Lösung
Gib die Spalten an, an denen du interessiert bist. Du möchtest zum Beispiel nur den Namen, die Abteilungsnummer und das Gehalt der Mitarbeiter sehen:
1 select ename,deptno,sal 2 from emp
Diskussion
Indem du die Spalten in der SELECT-Klausel angibst, stellst du sicher, dass keine überflüssigen Daten zurückgegeben werden. Das kann besonders wichtig sein, wenn du Daten über ein Netzwerk abrufst, da du so keine Zeit verschwendest, wenn du Daten abrufst, die du nicht brauchst.
1.5 Sinnvolle Namen für Spalten vergeben
Problem
Du möchtest die Namen der Spalten, die von deiner Abfrage zurückgegeben werden, ändern, damit sie besser lesbar und verständlich sind. Betrachte diese Abfrage, die die Gehälter und Provisionen für jeden Mitarbeiter zurückgibt:
1 select sal,comm 2 from emp
Was ist SAL? Ist es die Abkürzung für Sale? Ist es der Name von jemandem? Was ist COMM? Heißt es Kommunikation? Du möchtest, dass die Ergebnisse aussagekräftigere Bezeichnungen haben.
Lösung
Um die Namen der Abfrageergebnisse zu ändern, verwenden Sie das Schlüsselwort AS in der Formoriginal_name AS new_name
. Einige Datenbanken verlangen kein AS, aber alle akzeptieren es:
1 select sal as salary, comm as commission
2 from emp
SALARY COMMISSION ------- ---------- 800 1600 300 1250 500 2975 1250 1400 2850 2450 3000 5000 1500 0 1100 950 3000 1300
Diskussion
Wenn du das Schlüsselwort AS verwendest, um den von deiner Abfrage zurückgegebenen Spalten neue Namen zu geben, nennt man das Aliasing dieser Spalten. Die neuen Namen, die du vergibst, werden als Aliasnamen bezeichnet. Gute Aliasnamen können viel dazu beitragen, dass eine Abfrage und ihre Ergebnisse für andere verständlich sind.
1.6 Verweis auf eine Aliased-Spalte in der WHERE-Klausel
Problem
Du hast Aliasnamen verwendet, um aussagekräftigere Spaltennamen für deine Ergebnismenge zu erhalten, und möchtest einige der Zeilen mit der WHERE-Klausel ausschließen. Dein Versuch, in der WHERE-Klausel auf Aliasnamen zu verweisen, schlägt jedoch fehl:
select sal as salary, comm as commission from emp where salary < 5000
Lösung
Wenn du deine Abfrage als Inline-View verpackst, kannst du auf die Aliased-Spalten verweisen:
1 select * 2 from ( 3 select sal as salary, comm as commission 4 from emp 5 ) x 6 where salary < 5000
Diskussion
In diesem einfachen Beispiel kannst du die Inline-Ansicht umgehen und COMM oder SAL direkt in der WHERE-Klausel referenzieren, um das gleiche Ergebnis zu erzielen. Mit dieser Lösung erfährst du, was du tun musst, wenn du in einer WHERE-Klausel auf eines der folgenden Elemente verweisen willst:
-
Aggregatfunktionen
-
Skalare Unterabfragen
-
Fensterfunktionen
-
Aliasnamen
Wenn du deine Abfrage, die dir Aliase gibt, in einer Inline-Ansicht platzierst, kannst du in deiner äußeren Abfrage auf die Aliasspalten verweisen. Warum musst du das tun? Die WHERE-Klausel wird vor der SELECT-Abfrage ausgewertet; daher sind SALARY und COMMISSION noch nicht vorhanden, wenn die WHERE-Klausel der "Problem"-Abfrage ausgewertet wird. Diese Aliasnamen werden erst nach der Verarbeitung der WHERE-Klausel angewendet. Die FROM-Klausel wird jedoch vor der WHERE-Klausel ausgewertet. Wenn du die ursprüngliche Abfrage in eine FROM-Klausel einfügst, werden die Ergebnisse dieser Abfrage vor der äußersten WHERE-Klausel generiert, und deine äußerste WHERE-Klausel "sieht" die Alias-Namen. Diese Technik ist besonders nützlich, wenn die Spalten in einer Tabelle nicht besonders gut benannt sind.
Tipp
Die Inline-View in dieser Lösung ist ein Aliasing X. Nicht alle Datenbanken verlangen, dass eine Inline-View explizit mit einem Aliasing versehen wird, aber einige schon. Alle akzeptieren sie.
1.7 Verkettung von Spaltenwerten
Problem
Du möchtest Werte in mehreren Spalten als eine Spalte zurückgeben. Du möchtest zum Beispiel diese Ergebnismenge aus einer Abfrage der Tabelle EMP erzeugen:
CLARK WORKS AS A MANAGER KING WORKS AS A PRESIDENT MILLER WORKS AS A CLERK
Die Daten, die du für die Erstellung dieser Ergebnismenge brauchst, stammen jedoch aus zwei verschiedenen Spalten, den Spalten ENAME und JOB in der Tabelle EMP:
select ename, job
from emp
where deptno = 10
ENAME JOB ---------- --------- CLARK MANAGER KING PRESIDENT MILLER CLERK
Lösung
Finde die integrierte Funktion deines DBMS und verwende sie, um Werte aus mehreren Spalten zu verketten.
DB2, Oracle, PostgreSQL
Diese Datenbanken verwenden den doppelten vertikalen Balken als Verkettungsoperator:
1 select ename||' WORKS AS A '||job as msg 2 from emp 3 where deptno=10
1.8 Verwendung der bedingten Logik in einer SELECT-Anweisung
Problem
Du möchtest IF-ELSE-Operationen für Werte in deiner SELECT-Anweisung durchführen. Du möchtest zum Beispiel eine Ergebnismenge erzeugen, die bei einem Gehalt von 2.000 USD oder weniger die Meldung "UNTERBEZAHLT" ausgibt, bei einem Gehalt von 4.000 USD oder mehr die Meldung "ÜBERBEZAHLT" und bei einem Gehalt dazwischen die Meldung "OK" ausgibt. Die Ergebnismenge sollte wie folgt aussehen:
ENAME SAL STATUS ---------- ---------- --------- SMITH 800 UNDERPAID ALLEN 1600 UNDERPAID WARD 1250 UNDERPAID JONES 2975 OK MARTIN 1250 UNDERPAID BLAKE 2850 OK CLARK 2450 OK SCOTT 3000 OK KING 5000 OVERPAID TURNER 1500 UNDERPAID ADAMS 1100 UNDERPAID JAMES 950 UNDERPAID FORD 3000 OK MILLER 1300 UNDERPAID
Diskussion
Mit dem CASE-Ausdruck kannst du eine Bedingungslogik auf die von einer Abfrage zurückgegebenen Werte anwenden. Du kannst einen Alias für einen CASE-Ausdruck angeben, um eine besser lesbare Ergebnismenge zu erhalten. In der Lösung siehst du den Alias STATUS für das Ergebnis des CASE-Ausdrucks. Die ELSE-Klausel ist optional. Wenn du die ELSE-Klausel weglässt, gibt der CASE-Ausdruck für jede Zeile, die die Testbedingung nicht erfüllt, NULL zurück.
1.9 Begrenzung der Anzahl der zurückgegebenen Zeilen
Lösung
Verwende die integrierte Funktion deiner Datenbank, um die Anzahl der zurückgegebenen Zeilen zu steuern.
Diskussion
Viele Anbieter bieten Klauseln wie FETCH FIRST und LIMIT, mit denen du die Anzahl der Zeilen festlegen kannst, die von einer Abfrage zurückgegeben werden sollen. Bei Oracle musst du eine Funktion namens ROWNUM verwenden, die für jede zurückgegebene Zeile eine Zahl zurückgibt (einen aufsteigenden Wert, der bei eins beginnt).
So sieht es aus, wenn du ROWNUM <= 5 verwendest, um die ersten fünf Zeilen zurückzugeben:
-
Oracle führt deine Abfrage aus.
-
Oracle holt die erste Zeile und nennt sie Zeile Nummer eins.
-
Haben wir die Zeile Nummer fünf schon hinter uns gelassen? Wenn nein, dann gibt Oracle die Zeile zurück, weil sie das Kriterium erfüllt, dass sie kleiner oder gleich fünf ist. Wenn ja, dann gibt Oracle die Zeile nicht zurück.
-
Oracle holt die nächste Zeile und erhöht die Zeilennummer (auf zwei, dann auf drei, dann auf vier und so weiter).
-
Gehe zu Schritt 3.
Wie dieser Prozess zeigt, werden die Werte von Oracles ROWNUM zugewiesen , nachdem jede Zeile abgerufen wurde. Das ist ein wichtiger und entscheidender Punkt. Viele Oracle-Entwickler versuchen, z. B. nur die fünfte Zeile einer Abfrage zurückzugeben, indem sie ROWNUM = 5 angeben.
Die Verwendung einer Gleichheitsbedingung in Verbindung mit ROWNUM ist eine schlechte Idee. Das passiert, wenn du versuchst, z. B. die fünfte Zeile mit ROWNUM = 5 zurückzugeben:
-
Oracle führt deine Abfrage aus.
-
Oracle holt die erste Zeile und nennt sie Zeile Nummer eins.
-
Sind wir schon bei Zeile Nummer fünf angelangt? Wenn nein, dann verwirft Oracle die Zeile, weil sie die Kriterien nicht erfüllt. Wenn ja, dann gibt Oracle die Zeile zurück. Aber die Antwort wird niemals "Ja" sein!
-
Oracle holt die nächste Zeile und nennt sie Zeile Nummer eins. Das liegt daran, dass die erste Zeile, die von der Abfrage zurückgegeben wird, die Nummer eins haben muss.
-
Gehe zu Schritt 3.
Wenn du dir diesen Prozess genau ansiehst, kannst du sehen, warum die Verwendung von ROWNUM = 5 zur Rückgabe der fünften Zeile fehlschlägt. Du kannst keine fünfte Zeile haben, wenn du nicht zuerst die Zeilen eins bis vier zurückgibst!
Du wirst feststellen, dass ROWNUM = 1 tatsächlich die erste Zeile zurückgibt, was der bisherigen Erklärung zu widersprechen scheint. Der Grund dafür, dass ROWNUM = 1 die erste Zeile zurückgibt, ist, dass Oracle mindestens einmal versuchen muss, eine Zeile aus der Tabelle zu holen, um festzustellen, ob sie überhaupt vorhanden ist. Lies dir den vorangegangenen Vorgang genau durch und ersetze eine durch fünf, dann verstehst du, warum es in Ordnung ist, ROWNUM = 1 als Bedingung (für die Rückgabe einer Zeile) anzugeben.
1.10 Rückgabe von n zufälligen Datensätzen aus einer Tabelle
Lösung
Nimm eine beliebige integrierte Funktion, die von deinem DBMS unterstützt wird, um Zufallswerte zurückzugeben. Verwende diese Funktion in einer ORDER BY-Klausel, um Zeilen nach dem Zufallsprinzip zu sortieren. Verwende dann die Technik aus dem vorherigen Rezept, um die Anzahl der zufällig sortierten Zeilen zu begrenzen.
Diskussion
Die ORDER BY-Klausel kann den Rückgabewert einer Funktion akzeptieren und ihn verwenden, um die Reihenfolge der Ergebnismenge zu ändern. Diese Lösungen schränken alle die Anzahl der Zeilen ein, die nach der Ausführung der Funktion in der ORDER BY-Klausel zurückgegeben werden. Für Nicht-Oracle-Benutzer ist es vielleicht hilfreich, sich die Oracle-Lösung anzuschauen, da sie (konzeptionell) zeigt, was unter der Oberfläche der anderen Lösungen passiert.
Es ist wichtig, dass du die Verwendung einer Funktion in der ORDER BY-Klausel nicht mit der Verwendung einer numerischen Konstante verwechselst. Wenn du eine numerische Konstante in der ORDER BY-Klausel angibst, verlangst du, dass die Sortierung nach der Spalte an der entsprechenden Position in der SELECT-Liste erfolgt. Wenn du eine Funktion in der ORDER BY-Klausel angibst, wird die Sortierung nach dem Ergebnis der Funktion durchgeführt, wenn sie für jede Zeile ausgewertet wird.
1.11 Suche nach Nullwerten
Lösung
Um festzustellen, ob ein Wert null ist, musst du IS NULL verwenden:
1 select * 2 from emp 3 where comm is null
Diskussion
NULL ist niemals gleich/nicht gleich, nicht einmal sich selbst; daher kannst du nicht mit = oder != testen, ob eine Spalte NULL ist. Um festzustellen, ob eine Zeile NULL-Werte hat, musst du IS NULL verwenden. Du kannst auch IS NOT NULL verwenden, um Zeilen zu finden, die keine Nullwerte in einer bestimmten Spalte enthalten.
1.12 Nullen in reale Werte umwandeln
Diskussion
Die Funktion COALESCE nimmt einen oder mehrere Werte als Argumente an. Die Funktion gibt den ersten Wert in der Liste zurück, der nicht null ist. In der Lösung wird der Wert von COMM zurückgegeben, wenn COMM nicht null ist. Andernfalls wird eine Null zurückgegeben.
Wenn du mit Nullen arbeitest, ist es am besten, die integrierten Funktionen deines DBMS zu nutzen; in vielen Fällen wirst du feststellen, dass mehrere Funktionen für diese Aufgabe genauso gut funktionieren. COALESCE funktioniert zufällig bei allen DBMSs. Auch CASE kann für alle DBMS verwendet werden:
select case when comm is not null then comm else 0 end from emp
Du kannst zwar CASE verwenden, um Nullen in Werte umzuwandeln, aber du wirst sehen, dass es viel einfacher und prägnanter ist, COALESCE zu verwenden.
1.13 Suche nach Mustern
Problem
Du möchtest Zeilen zurückgeben, die mit einem bestimmten Teilstring oder Muster übereinstimmen. Betrachte die folgende Abfrage und Ergebnismenge:
select ename, job
from emp
where deptno in (10,20)
ENAME JOB ---------- --------- SMITH CLERK JONES MANAGER CLARK MANAGER SCOTT ANALYST KING PRESIDENT ADAMS CLERK FORD ANALYST MILLER CLERK
Von den Beschäftigten in den Abteilungen 10 und 20 willst du nur die zurückgeben, die entweder ein "I" in ihrem Namen haben oder eine Stellenbezeichnung, die auf "ER" endet:
ENAME JOB ---------- --------- SMITH CLERK JONES MANAGER CLARK MANAGER KING PRESIDENT MILLER CLERK
Diskussion
Wenn er in einer LIKE-Mustererkennung verwendet wird, passt der Prozentoperator (%) auf eine beliebige Folge von Zeichen. Die meisten SQL-Implementierungen bieten auch den Unterstrich-Operator ("_"), um ein einzelnes Zeichen zu finden. Wenn du das Suchmuster "I" mit %-Operatoren einschließt, wird jede Zeichenkette zurückgegeben, die ein "I" (an einer beliebigen Position) enthält. Wenn du das Suchmuster nicht mit % einschließt, hat die Position des Operators Auswirkungen auf die Ergebnisse der Abfrage. Wenn du z. B. Aufträge finden willst, die auf "ER" enden, stellst du den%-Operator vor "ER"; wenn du nach allen Aufträgen suchen willst, die mit "ER" beginnen, fügst du den %-Operator an "ER" an.
Get SQL Kochbuch, 2. Auflage now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.