Es sein $ b $ eine Funktion, die jedem Tupel der Art $ (a_1:v_1, \ldots, a_n:v_n) $ einen booleschen Wert (true/$ \top $, false/$ \bot $, unknown/$ U $) zuweist. Dabei seien $ a_1, \ldots a_n $ Attributnamen und $ v_1, \ldots v_n $ Werte der zugehörigen Domänen$ D_1, \ldots D_n $.
Die Selektionsfunktion
$ σ_b: R \rightharpoonup R $
überprüft für jedes Tupel $ (a_1:v_1, \ldots, a_n:v_n) $ einer Relation $ r $, die nur Tupel dieser Art enthält,
ob die Bedingungsfunktion $ b $ für das jeweilige Tupel den Wert true liefert:
$ b((a_1:v_1, \ldots, a_n:v_n)) = \top $
Ist dies der Fall, so wird das entsprechende Tupel in die Ergebnisrelation eingefügt, anderenfalls wird es „entfernt“.
Für Relationen, die Tupel anderer Bauart enthalten, d. h. andere Attribute oder gleichnamige Attribute mit nicht-kompatiblen Domänen, ist die Selektionsfunktion
$ σ_b $ nicht definiert.
In SQL muss in der SELECT-Klausel immer eine Projektionsliste angegeben werden,
auch wenn gar keine Projektion benötigt wird. Da es in den folgenden Beispielen nur um die Selektion geht
(WHERE-Klausel), wird jeweils die Projektionsklausel SELECT *
verwendet. In produktivem Code sollte man dies vermeiden und in SELECT-Klausel immer alle benötigten Attribute
explizit aufzählen, da sich die Anzahl und die Reihenfolge der Attribute einer Tabelle im Laufe
der Zeit ändern kann (Schemaevolution).
Selektion aller Tupel der Tabelle haendler (Identität)
SELECT*FROMhaendlerWHEREtrue
$ \texttt{haendler} $
→
$ σ_{\top}(\texttt{haendler}) $
h_id
h_name
h_ortschaft
1
Maier
Königsbrunn
2
Müller
Königsbrunn
3
Maier
Augsburg
4
Huber
NULL
5
Schmidt
Hamburg
→
h_id
h_name
h_ortschaft
1
Maier
Königsbrunn
2
Müller
Königsbrunn
3
Maier
Augsburg
4
Huber
NULL
5
Schmidt
Hamburg
Selektion von keinem einzigen Tupel der Tabelle haendler
$ σ_{\texttt{h_name LIKE 'M%'}}(\texttt{haendler}) $
h_id
h_name
h_ortschaft
1
Maier
Königsbrunn
2
Müller
Königsbrunn
3
Maier
Augsburg
4
Huber
NULL
5
Schmidt
Hamburg
→
h_id
h_name
h_ortschaft
1
Maier
Königsbrunn
2
Müller
Königsbrunn
3
Maier
Augsburg
Selektion aller Händler, die mindestens drei Warenangebote haben
Es ist auch möglich, komplexe Unteranfragen zur Selektion zu verwenden, wenn diese einen booelschen Wert als Ergebnis liefern.
Im folgenden Beispiel wird für jeden Händler mittels eine Aggregationsfunktion gezählt,
wie viele Warenangebote er hat, d. h., wie oft seine h_id in der Tabelle liefert vorkommt. Diejenigen Händler, für die dieser
Wert größer oder gleich drei ist, werden in der Ergebnistabelle aufgelistet.
$ σ_{\texttt{h_ortschaft LIKE '%burg'}}(\texttt{haendler}) $
h_id
h_name
h_ortschaft
1
Maier
Königsbrunn
2
Müller
Königsbrunn
3
Maier
Augsburg
4
Huber
NULL
5
Schmidt
Hamburg
→
h_id
h_name
h_ortschaft
3
Maier
Augsburg
5
Schmidt
Hamburg
Achtung: Dies ist eine teure Operation, da die Gesamte Händler-Tabelle durchlaufen und jeder Händlername überprüft werden muss.
Endtrunkierung sollte grundsätzlich vermieden werden. Stattdessen sollte man einen Volltextindex verwenden, der Endtrunkierung unterstützt.
Selektion aller liefert-Tupel, bei denen die Lieferzeit bekannt ist
SELECT*FROMliefertWHEREl_lieferzeitISNOTNULL;
$ \texttt{liefert} $
→
$ σ_{\texttt{l_lieferzeit IS NOT NULL}}(\texttt{liefert}) $
h_id
w_id
l_preis
l_lieferzeit
1
1
200.00
1
1
1
194.00
6
1
2
100.00
NULL
1
3
150.00
7
1
4
10.00
1
1
5
5.00
1
2
1
160.00
NULL
2
1
190.00
1
2
2
180.00
NULL
2
3
170.00
4
3
1
195.00
2
3
2
190.00
1
4
1
150.00
3
4
3
180.00
5
4
3
199.00
1
→
h_id
w_id
l_preis
l_lieferzeit
1
1
200.00
1
1
1
194.00
6
1
3
150.00
7
1
4
10.00
1
1
5
5.00
1
2
1
190.00
1
2
3
170.00
4
3
1
195.00
2
3
2
190.00
1
4
1
150.00
3
4
3
180.00
5
4
3
199.00
1
Selektion aller liefert-Tupel, bei denen die Lieferzeit unbekannt ist
SELECT*FROMliefertWHEREl_lieferzeitISNOTNULL;
$ \texttt{liefert} $
→
$ σ_{\texttt{l_lieferzeit IS NOT NULL}}(\texttt{liefert}) $
h_id
w_id
l_preis
l_lieferzeit
1
1
200.00
1
1
1
194.00
6
1
2
100.00
NULL
1
3
150.00
7
1
4
10.00
1
1
5
5.00
1
2
1
160.00
NULL
2
1
190.00
1
2
2
180.00
NULL
2
3
170.00
4
3
1
195.00
2
3
2
190.00
1
4
1
150.00
3
4
3
180.00
5
4
3
199.00
1
→
h_id
w_id
l_preis
l_lieferzeit
1
2
100.00
NULL
2
1
160.00
NULL
2
2
180.00
NULL
Weitere – eher sinnlose – Anfragen an die liefert-Tabelle
Für welche liefert-Tupel ist die Lieferzeit und Händler-ID überein?
$ σ_{\texttt{(h_id = l_lieferzeit) IS UNKNOWN}}(\texttt{liefert}) $
h_id
w_id
l_preis
l_lieferzeit
1
2
100.00
NULL
2
1
160.00
NULL
2
2
180.00
NULL
Man kann Selektionsbedingungen auch in die Select-Klausel an Stelle der Where-Klausel schreiben. Dann erfolgt allerdings keine Selektion,
sondern die Testergebnise werden als zusätzliche Attribute ausgegeben.
SELECTh_id,w_id,l_preis,l_lieferzeit,(h_id=w_idANDl_preis>l_lieferzeit)AS"h_id=w_id AND l_preis > l_lieferzeit",(h_id=w_idORl_preis>l_lieferzeit)AS"h_id=w_id OR l_preis > l_lieferzeit",(h_id=w_idORl_preis<l_lieferzeit)AS"h_id=w_id OR l_preis < l_lieferzeit"FROMliefert
$ π_{\texttt{h_id},\, \texttt{w_id}, \texttt{l_preis},\, \texttt{l_lieferzeit},\, \texttt{h_id=w_id AND l_preis} > \texttt{l_lieferzeit AS "h_id=w_id AND l_preis} > \texttt{l_lieferzeit"},\, \ldots}(\texttt{liefert}) $
h_id
w_id
l_preis
l_lieferzeit
h_id=w_id AND l_preis > l_lieferzeit
h_id=w_id OR l_preis > l_lieferzeit
h_id=w_id OR l_preis < l_lieferzeit
1
1
200.00
1
true
true
true
1
1
194.00
6
true
true
true
1
2
100.00
NULL
false
NULL
NULL
1
3
150.00
7
false
true
false
1
4
10.00
1
false
true
false
1
5
5.00
1
false
true
false
2
1
160.00
NULL
false
NULL
NULL
2
1
190.00
1
false
true
false
2
2
180.00
NULL
NULL
true
true
2
3
170.00
4
false
true
false
3
1
195.00
2
false
true
false
3
2
190.00
1
false
true
false
4
1
150.00
3
false
true
false
4
3
180.00
5
false
true
false
4
3
199.00
1
false
true
false
Für welche liefert-Tupel ist die Lieferzeit gleich (=) NULL?
SELECT*FROMliefertWHEREl_lieferzeit=NULL;-- an Stelle von l_lieferzeit IS NULL
Der Test auf Gleicheit eines Wertes mit NULL liefert stets den Wert UNKNOWN. Daher ist das Ergebnis der Anfrage leer.
Korrekt wäre der Test l_lieferzeit IS NULL.
Noch einmal Tests mit NULL
Fehlerhafter Test = NULL:
SELECT1ASergebnisWHERE5+NULL=NULL;
$ \texttt{leere_tabelle} $
→
$ σ_{\bot}(\texttt{haendler}) $
→
ergebnis
Korrekter Test IS NULL:
SELECT1ASergebnisWHERE5+NULLISNULL;
$ \texttt{leere_tabelle} $
→
$ σ_{\bot}(\texttt{haendler}) $
→
ergebnis
1
Diese Anfragen sind nicht standard-konform, werden aber sowohl von Postgres als auch von SQLite unterstützt. Laut SQL-Standard muss eine Select-Anweisung eine From-Klausel enthalten.[1] Das heißt,
müsste man eine Tabelle (z. B. mit Namen one) definieren, die genau Zeile enthält, und in diese beiden Queries eine passende FROM-Klausel (z. B. FROM one) einfügen.
Quellen
↑, <query specification>, S. 476, <table expression>, S. 390