Einfache Abfragen

Inhaltsübersicht

 

Einfache Abfragen. 1

7     Einfache Abfragen. 2

7.1     Grundform der SELECT-Anweisung. 2

7.2     Die WHERE-Klausel 5

7.2.1     Boolesche Funktionen. 7

7.2.2     Die Operatoren IN und BETWEEN.. 12

7.2.3     Der NULL-Operator 16

7.2.4     Der Operator LIKE. 18

7.3     Einfache Unterabfragen. 21

7.3.1     Unterabfrage und Vergleichsoperatoren. 22

7.3.2     Unterabfragen und IN-Operator 23

7.3.3     Die Operatoren ANY und ALL. 26

7.3.4     Der Operator EXISTS. 29

7.4     Die GROUP BY-Klausel 30

7.5     Aggregatfunktionen. 32

7.5.1     Die Funktionen MIN und MAX.. 33

7.5.2     Die Funktion SUM... 35

7.5.3     Die Funktion AVG.. 36

7.5.4     Die Funktion COUNT. 37

7.6     Die HAVING-Klausel 40

7.7     Die ORDER BY-Klausel 41

7.8     Der Mengenoperator UNION.. 44

Aufgaben. 49

 

 

 

 

7      Einfache Abfragen

 

 

         In den  nächsten beiden  Kapiteln werden  wir die  wichtigste

         SQL-Anweisung,  nämlich  SELECT  vorstellen.  Dieses  Kapitel

         dient der Einführung der SELECT-Anweisung und der Erläuterung

         einfacher   Abfragen.  Jede   Klausel  der   SELECT-Anweisung

         wird  separat erklärt  und mit  Hilfe  der  Beispieldatenbank

         dargestellt.  In dem  zweiten Teil  des Kapitels  werden  die

         Aggregatfunktionen und der Operator UNION beschrieben.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.1        Grundform der SELECT-Anweisung

 

 

 

         Mit   der  SELECT-Anweisung   werden  Datenwerte   aus  einer

         Datenbank ausgewählt. Sie können aus einer oder aus mehreren,

         miteinander   verbundenen  Tabellen  ausgewählt  werden.  Das

         Ergebnis  einer solchen  Auswahl ist erneut eine Tabelle, die

         keine, eine oder mehrere Reihen und eine oder mehrere Spalten

         hat.

 

         Die SELECT-Anweisung hat folgende allgemeine Form:

 

                SELECT [ALL|DISTINCT] *|{ausdr_1 AS alias_name1 },...

                     FROM tab1 [tab_alias1] [,tab_2 [tab_alias2],...]

                       [WHERE bedingung_1]

                       [GROUP BY ausdr_3,...]

                       [HAVING bedingung_2]

                       [ORDER BY ausdr_5 [ASC|DESC],...];

 

         Die einzelnen  Klauseln werden wir im Verlauf dieses Kapitels

         vorstellen und anhand von Beispielen praktisch erläutern.

 

         Wie  aus   der  allgemeinen   Form  ersichtlich,   beinhaltet

         die  einfachste  SELECT-Anweisung,  neben  SELECT,  noch  die

         FROM-Klausel:

 

                SELECT [ALL|DISTINCT] *|{ausdr_1 AS alias_name1} ,...

                    FROM tab1 [tab_alias1] [,tab_2 [tab_alias2],...];

 

         tab_1 kennzeichnet  den Namen  der  Tabelle,  aus  der  Daten

         ausgewählt  werden.  tab_alias1  stellt  den  Aliasnamen  der

         Tabelle tab1  dar. In  einer SELECT-Anweisung  können mehrere

         Tabellen  angegeben   werden.  In  diesem  Kapitel  wird  nur

         die Auswahl  der  Daten  aus  einer  Tabelle  behandelt.  Die

         Verknüpfung  mehrerer Tabellen in einer SELECT-Anweisung wird

         Thema von Kapitel 8 sein.

 

         Falls  die  SELECT-Anweisung  nur  den  Namen  einer  Tabelle

         beinhaltet,   werden  mit  ihr  alle  Reihen  und  eine  oder

         mehrere  Spalten   dieser  Tabelle  ausgewählt.  Das  Zeichen

         "*"  kennzeichnet alle  Spalten  aller  in  der  FROM-Klausel

         angegebenen Tabellen, während die explizite Auswahl einzelner

         Spaltennamen durch  die  Angabe  ausdr_1,  ...  erfolgt.  Die

         Auswahl der Spalten in einer SELECT-Anweisung wird Projektion

         und die Auswahl der Reihen Selektion genannt.

 

         Die Angabe  AS alias_name1  kann jedem  Ausdruck,  der  Bezug

         zu  einer einzelnen  Tabellenspalte hat,  zugewiesen  werden.

         In diesem  Fall wird  alias_name1 als  Spaltenüberschrift des

         Auswahlergebnisses verwendet.

 

 

         Beispiel 7.1

 

         Wählen Sie alle Reihen der Tabelle abteilung aus.

 

                 SELECT * FROM abteilung;

 

         Das Ergebnis ist:

      

abt_nr

abt_name 

stadt       

 a1   

Beratung 

Muenchen     

 a2   

Diagnose 

Muenchen     

 a3   

Freigabe 

Stuttgart    

                                                      

             (3 rows)

 

         Mit  dieser Anweisung werden alle Reihen und alle Spalten der

         Tabelle abteilung ausgewählt.

 

         Hinweis.

 

         SELECT * liefert die Spalten einer Tabelle in der Reihenfolge

         wie sie in der CREATE TABLE-Anweisung definiert  wurden.  Die

         Spaltennamen bilden die _berschrift.

 

         Beispiel 7.2

 

                       SELECT  abt_nr, abt_name, stadt

                          FROM abteilung;

 

         Das Ergebnis ist:

 

abt_nr

abt_name 

stadt       

 a1   

Beratung 

Muenchen     

 a2   

Diagnose 

Muenchen     

 a3   

Freigabe 

Stuttgart    

                                                         

             (3 rows)

 

         Das   Beispiel  7.2   liefert  dasselbe   Ergebnis  wie   die

         SELECT-Anweisung in Beispiel 7.1.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.2        Die WHERE-Klausel

 

 

         Die einfachste  Form der  SELECT-Anweisung wird in der Praxis

         nicht  so oft benutzt, wie die Form, in der eine oder mehrere

         Bedingungen  existieren. Die  Bedingungen  werden  mit  Hilfe

         der WHERE-Klausel  definiert, die  die auszuwählenden  Reihen

         bestimmt.

 

 

         Beispiel 7.3

 

         Finden  Sie  die  Namen und Nummern aller Abteilungen, die in

         München ihren Sitz haben.

 

                      SELECT abt_name, abt_nr

                         FROM abteilung

                         WHERE stadt = 'Muenchen';

 

         Das Ergebnis ist:

 

abt_name 

abt_nr

Beratung 

 a1   

Diagnose 

 a2   

 

            (2 rows)

 

         Die Bedingung  in einer  WHERE-Klausel  muß  nicht  unbedingt

         auf   Gleichheit   geprüft   werden.   SQL   kennt   folgende

         Vergleichsoperatoren:

                                             

Operator

Funktion

=

gleich

<> oder !=  oder ^=

nicht gleich

>

groesser als

<

kleiner als

>=

groesser gleich

<=

kleiner gleich

 

 

         Beispiel 7.4

 

         Nennen  Sie  die  Namen und Vornamen aller Mitarbeiter, deren

         Personalnummer größer oder gleich 15000 ist.

 

                      SELECT m_name, m_vorname

                          FROM mitarbeiter

                          WHERE m_nr >= 15000;

 

         Das Ergebnis ist:

 

m_name 

m_name

Keller              

Hans              

Mueller             

Gabriele          

Probst              

Andreas           

Mozer               

Sibille            

 

            (4 rows)

 

         In der WHERE-Klausel können auch Ausdrücke erscheinen.

 

         Beispiel 7.5

 

         Finden  Sie alle Projekte, deren Finanzmittel mehr als 60000$

         betragen. Der augenblickliche Kurs soll bei 0,55 Dollar für 1

         DM liegen.

 

                          SELECT pr_name

                              FROM projekt

                              WHERE mittel * 0.55 > 60000;

 

         Das Ergebnis ist:

 

pr_name 

Apollo               

Merkur               

                                   

            (2 rows)

 

         Beim  Vergleich von  CHAR- bzw. VARCHAR-Ausdrücken werden die

         einzelnen  Zeichen auf  Grund der  ASCII-Tabelle  verglichen.

         Ein Zeichen  ist kleiner  als ein  anderes, falls  es in  der

         ASCII-Tabelle  vor diesem  Zeichen steht.  Gleichermaßen  ist

         ein Zeichen  größer als  ein anderes,  falls es hinter diesem

         Zeichen in  der ASCII-Tabelle  steht. Die  numerischen  Werte

         werden in  der üblichen mathematischen Weise verglichen. Beim

         Vergleich von  Ausdrücken vom  Typ DATE ist ein Datum kleiner

         als ein anderes, wenn es älter als dieses ist.

 

         Kommen in  einer Spalte  NULL-Werte vor  und  beinhaltet  die

         WHERE-Klausel  eine Bedingung  mit dieser Spalte, werden alle

         NULL-Werte  beim Vergleich  außer acht gelassen. (Im weiteren

         Verlauf  dieses Kapitels  werden wir zeigen, wie man explizit

         die NULL-Werte auswählen kann.)

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.2.1     Boolesche Funktionen

 

 

         Boolesche  Funktionen sind:  Konjunktion  ("logisches  UND"),

         Disjunktion ("logisches ODER") und Negation. Diese Funktionen

         werden durch  die Symbole  AND, OR  und NOT  dargestellt. Das

         Verhalten der  Operatoren AND, OR und NOT haben wir schon mit

         Hilfe der Wahrheitstabellen in Kapitel 2 gezeigt.

 

         Beispiel 7.6

 

         Gesucht  werden Personalnummer, Projektnummer und Aufgabe der

         Mitarbeiter, die im Projekt p2 Sachbearbeiter sind.

 

                        SELECT m_nr, pr_nr, aufgabe

                           FROM arbeiten

                           WHERE pr_nr = 'p2'

                           AND aufgabe = 'Sachbearbeiter';

 

         Das Ergebnis ist:

 

m_nr      

pr_nr

aufgabe            

25348

p2   

Sachbearbeiter     

28559

p2   

Sachbearbeiter     

                                                  

          (2 rows)

 

         Beim AND-Operator werden nur die Reihen ausgewählt, bei denen

         die beiden Bedingungen, die AND verbindet, erfüllt sind.

 

         Beispiel 7.7

 

         Gesucht wird die Personalnummer der Mitarbeiter, die entweder

         im Projekt p1 oder p2 oder in beiden arbeiten.

 

                          SELECT m_nr

                             FROM arbeiten

                             WHERE pr_nr = 'p1'

                             OR    pr_nr = 'p2';

 

         Das Ergebnis lautet:

 

m_nr         

10102

25348

18316

29346

9031

28559

28559

29346

 

          (8 rows)

 

         Im  Ergebnis des  Beispiels 7.7  sind einige  Datenwerte  der

         Spalte m_nr  mehrfach vorhanden. Falls jeder Datenwert dieser

         Spalte nur  einmal im  Ergebnis  vorkommen  sollte,  muß  die

         DISTINCT-Angabe benutzt werden:

 

 

                          SELECT DISTINCT m_nr

                             FROM arbeiten

                             WHERE pr_nr = 'p1'

                             OR    pr_nr = 'p2';

 

         Das Ergebnis lautet dann:

 

m_nr         

9031

10102

18316

25348

28559

29346

                        

            (6 rows)

 

         Im  Gegensatz  zu  AND werden bei dem Operator OR alle Reihen

         ausgewählt, bei denen wenigstens eine der Bedingungen erfüllt

         ist.

 

         Die  WHERE-Klausel kann mehrere gleiche oder unterschiedliche

         Boolesche Operatoren  beinhalten. Dabei  ist zu beachten, daß

         AND eine größere Priorität  als OR  hat.  Die  Nichtbeachtung

         dieser  Regel kann zu falschen Ergebnissen führen, wie wir am

         nächsten Beispiel sehen werden.

 

         Beispiel 7.8

 

                    SELECT *

                       FROM mitarbeiter

                       WHERE m_nr = 25348 AND m_name = 'Keller'

                       OR m_vorname = 'Hans' AND abt_nr = 'a1';

 

                    SELECT *

                       FROM mitarbeiter

                       WHERE ((m_nr = 25348 AND m_name = 'Keller')

                       OR m_vorname = 'Hans') AND abt_nr = 'a1';

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

abt_nr

25348

Keller              

Hans                

a3    

                                                                  

         (1 row)

 

m_nr   

m_name              

m_vorname           

abt_nr

 

 

 

 

                                                                  

         (0 rows)

 

         Wie    aus    dem    Ergebnis    ersichtlich,    haben    die

         SELECT-Anweisungen    in   Beispiel    7.8   unterschiedliche

         Ergebnisse. In  der ersten  SELECT-Anweisung werden  zunächst

         die  beiden Operationen mit AND ausgewertet (zuerst die linke

         und dann  die rechte);  die Operation mit OR wird erst danach

         durchgeführt.  In der  zweiten SELECT-Anweisung werden, unter

         Benutzung von Klammern, die Operationen von links nach rechts

         abgearbeitet.

 

         Bei   Verwendung  mehrerer  Boolescher  Operatoren  innerhalb

         einer   WHERE-Klausel,  ist   diese  in  den  meisten  Fällen

         schwer  verständlich. In  solchen Fällen empfiehlt sich daher

         grundsätzlich  die Benutzung  von Klammern,  auch  in  Fällen

         wo  sie nicht  unbedingt notwendig  sind. Dadurch  wird  eine

         SELECT-Anweisung  lesbarer.  Die  erste  SELECT-Anweisung  in

         Beispiel 7.8  hat durch  die Benutzung  von Klammern folgende

         Form:

 

                    SELECT *

                       FROM mitarbeiter

                       WHERE (m_nr = 25348 AND m_name = 'Keller')

                       OR (m_vorname = 'Hans' AND abt_nr = 'a1');

 

         Der dritte Boolesche Operator, NOT, ändert den logischen Wert

         einer Bedingung.  Wie man  aus der  Wahrheitstabelle für  NOT

         in  Kapitel 2  sehen kann,  ist die  Negation eines richtigen

         logischen  Wertes falsch,  eines falschen  richtig und  eines

         unbekannten  Wertes wieder  unbekannt. Die  Negation hat  von

         allen  drei Booleschen Operatoren die höchste Priorität. Wenn

         in  einem logischen Ausdruck alle drei Operatoren existieren,

         wird  also zuerst  die Negation,  danach das logische UND und

         erst am Ende das logische ODER abgearbeitet.

 

         Beispiel 7.9

 

         Nennen  Sie Personalnummer und Nachnamen der Mitarbeiter, die

         nicht in der Abteilung a2 arbeiten.

 

                      SELECT m_nr, m_name

                         FROM mitarbeiter

                         WHERE NOT abt_nr = 'a2';

 

         Das Ergebnis ist:

 

m_nr       

m_name             

25348

Keller             

10102

Huber              

18316

Mueller            

28559

Mozer              

                                            

            (4 rows)

 

         Der  Boolesche Operator NOT kann durch den Vergleichsoperator

         "<>"   (ungleich)  ersetzt  werden.  Beispiel  7.10  ist  mit

         Beispiel 7.9 identisch.

 

         Beispiel 7.10

 

                        SELECT m_nr, m_name

                           FROM mitarbeiter

                           WHERE abt_nr <> 'a2';

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.2.2     Die Operatoren IN und BETWEEN

 

 

         Mit  dem  IN-Operator  können  mehrere  Konstanten  angegeben

         werden, auf  die dann  die Suche  beschränkt wird.  Es werden

         lediglich die  Reihen ausgewählt, bei denen der Datenwert der

         Spalte  in der WHERE-Klausel einer der angegebenen Konstanten

         entspricht.

 

         Beispiel 7.11

 

         Finden  Sie  alle Mitarbeiter, deren Personalnummer entweder

         29346, 28559 oder 25348 ist.

 

                        SELECT *

                           FROM mitarbeiter

                           WHERE m_nr IN (29346, 28559, 25348);

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

abt_nr

25348

Keller           

Hans             

a3    

29346

Probst           

Andreas          

a2    

28559

Mozer            

Sibille          

a1    

                                                               

          (3 rows)

 

         Der IN-Operator  kann  durch  eine  Reihe  von  OR-Operatoren

         ersetzt  werden.   Beispiel  7.12   ist  mit   Beispiel  7.11

         identisch.

 

         Beispiel 7.12

 

                     SELECT *

                        FROM mitarbeiter

                        WHERE m_nr = 29346

                        OR    m_nr = 28559

                        OR    m_nr = 25348;

 

         Der  IN-Operator  kann  auch  gemeinsam  mit  dem  Booleschen

         Operator  NOT verwendet  werden. In  diesem Fall  werden  nur

         die Reihen  ausgewählt, für  die  der  Datenwert  der  Spalte

         in  der WHERE-Klausel  keine von  den angegebenen  Konstanten

         beinhaltet.

 

         Beispiel 7.13

 

         Nennen Sie alle Mitarbeiter, deren Personalnummer weder 10102

         noch 9031 ist.

 

                        SELECT *

                           FROM mitarbeiter

                           WHERE m_nr NOT IN (10102, 9031);

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

abt_nr

25348

Keller           

Hans             

a3    

18316

Mueller             

Gabriele            

a1    

29346

Probst           

Andreas          

a2    

2581

Kaufmann            

Brigitte            

a2    

28559

Mozer            

Sibille          

a1    

                                                                  

         (5 rows)

 

         Der IN-Operator kann auch für Unterabfragen verwendet werden.

         Diese Form  des IN-Operators  werden  wir  später  in  diesem

         Kapitel erörtern.

 

         Im  Unterschied zum IN-Operator, der einzelne Werte festlegt,

         definiert der Operator BETWEEN immer einen  Bereich,  in  dem

         dann die Werte gesucht werden, die die Bedingung erfüllen.

 

         Beispiel 7.14

 

         Nennen Sie Namen und Mittel aller Projekte, deren finanzielle

         Mittel zwischen 95.000 DM und 120.000 DM liegen.

 

                        SELECT pr_name, mittel

                           FROM projekt

                           WHERE mittel BETWEEN 95000 AND 120000;

 

         Das Ergebnis ist:

 

pr_name                      

mittel       

Apollo                          

120000.000

Gemini                            

95000.000

                                                        

            (2 rows)

 

         Wie  aus   Beispiel  7.14  ersichtlich  ist,  beinhaltet  der

         Bereich auch die beiden Grenzwerte, die beim BETWEEN-Operator

         angegeben sind.

 

         Der  BETWEEN-Operator kann  auch  durch  Vergleichsoperatoren

         ersetzt werden. Beispiel 7.15 entspricht dem Beispiel 7.14.

 

         Beispiel 7.15

 

                        SELECT pr_name, mittel

                           FROM projekt

                           WHERE mittel <= 120000

                           AND   mittel >=  95000;

 

         Obwohl   die  beiden  SELECT-Anweisungen  in  den  Beispielen

         7.14  und   7.15  identisch   sind,  ist  die  Form  mit  dem

         BETWEEN-Operator  vorzuziehen.  Die  Anweisung  in  7.14  ist

         transparenter und deswegen leichter lesbar.

 

         Der   BETWEEN-Operator  kann,   in  gleichem   Maße  wie  der

         IN-Operator,   mit  dem  Booleschen  Operator  NOT  gemeinsam

         verwendet  werden.   In  diesem   Fall  werden   die   Reihen

         ausgewählt,  für   die  der   Datenwert  der  Spalte  in  der

         WHERE-Klausel außerhalb des angegebenen Bereichs liegt.

 

         Beispiel 7.16

 

         Nennen  Sie   die  Personalnummer   aller  Mitarbeiter,   die

         Projektleiter sind und vor oder nach 1988 eingestellt wurden.

 

           SELECT m_nr

            FROM arbeiten

            WHERE aufgabe = 'Projektleiter'

            AND einst_dat NOT BETWEEN '01-jan-1988' AND '31-dec-1988';

 

         Das Ergebnis ist:

 

m_nr     

2581

                     

           (1 row)

 

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.2.3     Der NULL-Operator

 

 

         Wie schon  in Kapitel  2  erwähnt,  werden  NULL-Werte  einer

         Spalte  außer  acht  gelassen,  falls  in  der  WHERE-Klausel

         ausschließlich  Vergleichsoperatoren verwendet  worden  sind.

         Damit  auch   Datenwerte,  die   NULL-Werte  beinhalten,   in

         einer   SELECT-Anweisung  ausgewählt   werden  können,  wurde

         der  NULL-Operator eingeführt.  Die  allgemeine  Form  dieses

         Operators ist:

 

                        spalte_1 IS [NOT] NULL

 

         Beispiel 7.17

 

         Finden Sie die Personal- und Projektnummer aller Mitarbeiter,

         die im  Projekt p1  arbeiten und  deren  Aufgabe  noch  nicht

         festgelegt ist.

 

                         SELECT m_nr, pr_nr

                            FROM arbeiten

                            WHERE pr_nr = 'p1'

                            AND aufgabe IS NULL;

 

         Das Ergebnis ist:

 

m_nr     

pr_nr

28559

p1   

                           

           (1 row)

 

         In   der  Syntax   des  NULL-Operators   befindet  sich  eine

         potentielle  Fehlerquelle beim  Programmieren  mit  SQL.  Der

         Vergleich auf  NULL bzw.  NOT NULL  wird nicht,  wie in allen

         anderen  Fällen mit  dem Vergleichsoperator "=" durchgeführt.

         Das liegt  an der  Logik des  NULL-Wertes. Dieser  Wert  kann

         nicht mit  einem  beliebigen  Wert  verglichen  werden,  oder

         ihm entsprechen.  Deswegen  wurde  bei  der  Syntaxdefinition

         absichtlich das Verb IS eingeführt.

 

         Die Bedingung

 

                      spalte_1 IS NOT NULL

 

         ist mit der Bedingung

 

                      NOT (spalte_1 IS NULL)

 

         identisch.

 

         Hinweis.

         Die Bedingung mit dem Vergleich auf NULL  bzw. NOT NULL kann

         richtig oder falsch, aber auf keinen Fall NULL sein!

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.2.4     Der Operator LIKE

 

 

         Der  LIKE-Operator ist ein Vergleichsoperator, der Datenwerte

         einer Spalte mit einem vorgegebenen  Muster  vergleicht.  Die

         allgemeine Form des LIKE-Operators ist

 

                       spalte_2 [NOT] LIKE 'muster'

 

         wobei   muster   eine   Zeichenkette   darstellt,   die   das

         Vergleichsmuster   definiert.  Diese   Zeichenkette   enthält

         alphanumerische Zeichen,  wobei zwei  Zeichen eine  besondere

         Bedeutung haben. Dies sind:

 

                        %    (Prozentzeichen)   und

                        _    (Unterstrich)

 

         Das Zeichen  "%" kennzeichnet eine beliebige Zeichenfolge von

         n Zeichen,  wobei n  eine nichtnegative  ganze Zahl ist, also

         auch 0 sein kann. Das Zeichen "_" kennzeichnet ein beliebiges

         alphanumerisches  Zeichen.   Jedes   andere   alphanumerische

         Zeichen kennzeichnet sich selbst.

 

         Beispiel 7.18

 

         Finden  Sie Namen und Personalnummer aller Mitarbeiter, deren

         Name mit dem Buchstaben "K" beginnt.

 

                             SELECT m_name, m_nr

                                FROM mitarbeiter

                                WHERE m_name LIKE 'K%';

 

         Das Ergebnis ist:

 

m_name              

m_nr   

Keller           

25348

Kaufmann                           

2581

                                                      

            (2 rows)

 

         Beispiel 7.19

 

         Nennen  Sie   Namen,  Vornamen   und   Personalnummer   aller

         Mitarbeiter, deren Vorname als zweiten Buchstaben "a" hat.

 

                         SELECT  m_nr, m_name, m_vorname

                            FROM mitarbeiter

                            WHERE m_vorname LIKE '_a%';

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

25348

Keller              

Hans                

18316

Mueller              

Gabriele            

9031

Meier               

Rainer              

                                                               

          (3 rows)

 

         Der  Benutzer kann  mit der  Angabe ESCAPE  selbst festlegen,

         welches Zeichen  als Entwertungszeichen  verwendet wird.  Die

         Angabe

 

                        spalte_3 LIKE '%z_%' ESCAPE 'z'

 

         sucht alle Datenwerte in der Spalte spalte_3, die das Zeichen

         "_" (Unterstrich)  an  irgendeiner  Stelle  der  Zeichenkette

         enthalten.

 

         Die Bedingung

 

                          spalte_4 NOT LIKE 'muster'

 

         ist identisch mit

 

                         NOT (spalte_4 LIKE 'muster')

 

         Beispiel 7.20

 

         Nennen Sie  alle Mitarbeiter,  deren Name  nicht  mit  "mann"

         endet.

 

 

                         SELECT *

                            FROM mitarbeiter

                            WHERE m_name NOT LIKE '%mann';

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

abt_nr

25348

Keller           

Hans             

a3    

10102

Huber               

Petra               

a3     

18316

Mueller             

Gabriele            

a1     

29346

Probst           

Andreas          

a2    

9031

Meier               

Rainer              

a2     

28559

Mozer            

Sibille          

a1    

                                                                    

         (6 rows)

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.3        Einfache Unterabfragen

 

 

         Bis  jetzt wurde der Vergleich in der WHERE-Klausel immer mit

         einer Konstanten bzw. einem Ausdruck durchgeführt. Zusätzlich

         dazu ist  es möglich,  den Vergleich  mit dem  Ergebnis einer

         weiteren SELECT-Anweisung  durchzuführen. Eine solche

         SELECTAnweisung,

                    die  Teil der  Bedingung einer  WHERE-Klausel ist,

         wird einfache  Unterabfrage  genannt.  (Neben  der  einfachen

         Unterabfrage gibt es auch die korrelierten Unterabfragen, die

         in Kapitel 8 erklärt werden.)

 

         Jede  Unterabfrage wird  häufig als  innere  SELECT-Anweisung

         bezeichnet, dies im Unterschied zur äußeren SELECT-Anweisung,

         in  der die  innere eingeschlossen  ist. In einer Abfrage mit

         einfacher Unterabfrage wird stets zunächst die innere

         SELECTAnweisung

                    ausgewertet und  ihr Ergebnis  dann an  die äußere

         SELECT-Anweisung weitergegeben.

 

         Eine einfache Unterabfrage kann im Zusammenhang mit folgenden

         Operatoren auftreten:

 

                        - allen Vergleichsoperatoren;

                        - dem IN-Operator;

                        - dem ANY bzw. ALL-Operator      und 

                        - dem EXISTS-Operator.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.3.1     Unterabfrage und Vergleichsoperatoren

 

 

         Beispiel 7.21

 

         Nennen  Sie  die  Abteilungsnummer  des  Mitarbeiters, der am

         15.10.1989 eingestellt wurde.

 

                        SELECT abt_nr

                           FROM mitarbeiter

                           WHERE m_nr =

                           (SELECT m_nr

                               FROM arbeiten

                               WHERE einst_dat = '15-oct-1989');

 

         Das Ergebnis ist:

 

abt_nr

 a2   

 

            (1 row)

 

 

         Wie  aus Beispiel  7.21 ersichtlich,  wird  die  Unterabfrage

         immer in Klammern eingeschlossen.

 

         Die     Unterabfrage    kann    auch    mit    den    anderen

         Vergleichsoperatoren im Zusammenhang stehen.

 

         Beispiel 7.22

 

         Nennen Sie die Nummern aller Projekte, in welchen Mitarbeiter

         arbeiten,  deren Personalnummer  kleiner als  die Nummer  des

         Mitarbeiters namens Mueller ist.

 

                        SELECT DISTINCT pr_nr

                           FROM arbeiten

                           WHERE m_nr <

                           (SELECT m_nr

                               FROM mitarbeiter

                               WHERE m_name = 'Mueller');

 

         Das Ergebnis ist:

 

pr_nr

 p1   

 p3   

                  

            (2 rows)

 

         Wie aus  den beiden  letzten Beispielen ersichtlich, darf die

         innere  SELECT-Anweisung nur einen Wert als Ergebnis liefern,

         falls   sie  im  Zusammenhang  mit  einem  Vergleichsoperator

         erscheint. Dies  ist auch  logisch, weil  der  Vergleich  mit

         mehreren Ergebniswerten nicht sinnvoll wäre.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.3.2     Unterabfragen und IN-Operator

 

 

         Wie  schon  im  vorherigen  Abschnitt  erklärt,  liefert  der

         IN-Operator  als Ergebnis  eine Anzahl  von  Konstanten,  die

         dann  mit den Datenwerten einer Spalte verglichen werden. Die

         Verwendung des  IN-Operators mit  der  Unterabfrage  verläuft

         ähnlich.  Die  innere  SELECT-Anweisung  liefert  einen  oder

         mehrere Ergebniswerte,  mit denen die Datenwerte einer Spalte

         verglichen werden.

 

         Beispiel 7.23

 

         Nennen  Sie die  Daten  aller  Mitarbeiter,  die  in  München

         arbeiten.

 

 

                        SELECT *

                           FROM mitarbeiter

                           WHERE abt_nr IN

                           (SELECT abt_nr

                               FROM abteilung

                               WHERE stadt = 'Muenchen');

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname           

abt_nr

18316

Mueller             

Gabriele            

a1    

29346

Probst           

Andreas          

a2    

9031

Meier               

Rainer              

a2    

2581

Kaufmann            

Brigitte            

a2    

28559

Mozer            

Sibille          

a1    

                                                                 

         (5 rows)

 

 

         Jede Unterabfrage  kann eine  weitere Unterabfrage enthalten.

         In diesem Fall sprechen wir von geschachtelten Unterabfragen.

         Die  Anzahl der  geschachtelten  Unterabfragen  ist  von  der

         Implementierung  und  von  dem  Speicherplatz  abhängig,  der

         für eine  Abfrage  (mit  allen  dazugehörigen  Unterabfragen)

         festgelegt   ist.   Bei   allen   geschachtelten,   einfachen

         Unterabfragen  wird zunächst  die  innerste  SELECT-Anweisung

         abgearbeitet   und  dann   das  Ergebnis   der  nächsthöheren

         SELECT-Anweisung übergeben. So wird weiter verfahren, bis die

         äußere SELECT-Anweisung erreicht und abgearbeitet wird.

 

         Beispiel 7.24

 

         Nennen Sie die Namen aller Mitarbeiter, die im Projekt Apollo

         arbeiten.

 

                 SELECT m_name

                    FROM mitarbeiter

                    WHERE m_nr IN

                    ( SELECT m_nr

                         FROM arbeiten

                         WHERE pr_nr =

                         ( SELECT pr_nr

                              FROM projekt

                              WHERE pr_name = 'Apollo'))

 

         Das Ergebnis ist:

 

        

m_name                   

Huber                    

Probst                   

Meier                    

Mozer                    

                                              

                   (4 rows)

 

         Die innerste  SELECT-Anweisung wählt den Datenwert der Spalte

         pr_nr (p1) der Tabelle projekt aus, dessen Projektname Apollo

         lautet. Die mittlere SELECT-Anweisung vergleicht anschliessend

         diesen  Wert mit  den Datenwerten  der  gleichnamigen  Spalte

         in   der  Tabelle   arbeiten.  Das   Ergebnis  der  mittleren

         SELECT-Anweisung  beinhaltet mehrere Werte, die mit Hilfe des

         IN-Operators  mit den  Datenwerten der  Spalte  m_nr  in  der

         Tabelle mitarbeiter verglichen werden.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.3.3     Die Operatoren ANY und ALL

 

 

         Die  Operatoren  ANY und ALL werden immer im Zusammenhang mit

         einem  Vergleichsoperator benutzt. Die allgemeine Form beider

         Operatoren ist:

 

 

               ausdruck vergl_op [ANY | ALL] (unterabfrage)    ,

 

 

         wobei vergl_op einen der Vergleichsoperatoren darstellt.

 

         Beim  ANY-Operator  wird  die Bedingung als wahr ausgewertet,

         falls  die  Unterabfrage wenigstens eine Reihe  als  Ergebnis

         liefert, die dem angegebenen Vergleich entspricht.

 

         Beispiel 7.25

 

         Finden  Sie Personalnummer,  Projektnummer  und  Aufgabe  der

         Mitarbeiter,  deren   Eintrittsdatum  in   das  entsprechende

         Projekt nicht das älteste ist.

 

                        SELECT m_nr, pr_nr, aufgabe

                           FROM arbeiten

                           WHERE einst_dat > ANY

                           (SELECT einst_dat

                               FROM arbeiten);

 

         Das Ergebnis ist:

 

      

m_nr   

pr_nr

aufgabe           

10102

p1   

Projektleiter     

10102

p3   

Gruppenleiter     

25348

p2   

Sachbearbeiter    

18316

p2                      

 

2581

p3   

Projektleiter     

9031

p1   

Gruppenleiter     

28559

p1                      

 

28559

p2   

Sachbearbeiter    

9031

p3   

Sachbearbeiter    

29346

p1   

Sachbearbeiter    

                                         

        (10 rows)

 

         In Beispiel  7.25 wird  jeder Datenwert  der Spalte einst_dat

         mit allen Datenwerten derselben Spalte (auch mit sich selbst)

         verglichen. Für  alle Datenwerte,  abgesehen von einem, gilt,

         daß beim  Vergleich die  Bedingung wenigstens  in einem  Fall

         erfüllt  ist. Die  Reihe mit dem ältesten Eintrittsdatum wird

         nicht ausgewählt,  weil für  sie der  Vergleich nicht erfüllt

         ist.

 

         Beispiel 7.26

 

         Nennen  Sie  die Namen und Vornamen aller Mitarbeiter, die im

         Projekt p1 arbeiten.

 

                        SELECT m_name, m_vorname

                           FROM mitarbeiter

                           WHERE m_nr = ANY

                           (SELECT m_nr

                               FROM arbeiten

                               WHERE pr_nr = 'p1');

 

         Das Ergebnis ist:

 

m_name              

m_vorname           

Huber               

Petra              

Probst           

Andreas          

Meier               

Rainer             

Mozer            

Sibille          

                                                     

            (4 rows)

 

         Beim  ALL-Operator wird  die Bedingung  als wahr ausgewertet,

         wenn   alle  Ergebnisse   der  Unterabfrage  dem  angegebenen

         Vergleich entsprechen.

 

         Beispiel 7.27

 

         Nennen  Sie  die  Aufgabe  des Mitarbeiters, der die kleinste

         Personalnummer hat.

 

                        SELECT aufgabe

                           FROM arbeiten

                           WHERE m_nr <= ALL

                           (SELECT m_nr

                               FROM mitarbeiter);

 

         Das Ergebnis ist:

 

aufgabe              

Projektleiter        

                                  

            (1 row)

 

         Neben  den Operatoren ANY und ALL existiert noch ein Operator

         - SOME. Dieser Operator ist gleichbedeutend mit ANY.

 

         Die  Operatoren ALL  und  ANY  haben  einige  Nachteile,  die

         gegen ihre  Verwendung bei Unterabfragen sprechen. Der größte

         Nachteil ist,  daß die  korrekte semantische Bedeutung beider

         Operatoren verwechselt  werden kann.  Auf der  anderen  Seite

         können die beiden Operatoren leicht durch den EXISTS-Operator

         ersetzt werden,  wie wir im nächsten Kapitel  zeigen  werden.

         Deswegen  empfehlen wir, die Verwendung beider Operatoren auf

         ein Minimum zu reduzieren.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.3.4     Der Operator EXISTS

 

 

         Der EXISTS-Operator  prüft das  Ergebnis einer  Unterabfrage;

         falls  die Unterabfrage  zumindest eine  Reihe  als  Ergebnis

         liefert,  wird die  Bedingung als wahr ausgewertet. Falls die

         Unterabfrage keine  Reihe  als  Ergebnis  liefert,  wird  die

         Bedingung in der WHERE-Klausel als falsch ausgewertet.

 

         Die allgemeine Form des EXISTS-Operators ist:

 

                        [NOT] EXISTS (unterabfrage)

 

         Die Beispiele zum EXISTS-Operator finden Sie in Kapitel 8.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.4        Die GROUP BY-Klausel

 

 

         Die  GROUP BY-Klausel definiert eine oder mehrere Spalten als

         Gruppenkennzeichen, wonach die Reihen gruppiert werden.

 

         Beispiel 7.28

 

         Welche Aufgaben üben die Mitarbeiter der Firma aus?

 

                        SELECT aufgabe

                           FROM arbeiten

                           GROUP BY aufgabe;

 

         Das Ergebnis ist:

aufgabe                 

Projektleiter           

Gruppenleiter           

Sachbearbeiter          

                                    

            (4 rows)

 

         Wie wir  aus Beispiel  7.28  ersehen  können, baut  die GROUP

         BY-Klausel für  jeden unterschiedlichen  Datenwert (auch  für

         den  NULL-Wert) der  genannten Spalte  eine Gruppe auf. Falls

         die GROUP  BY-Klausel angegeben  ist, muß  jede Spalte in der

         Projektion auch  in der  GROUP BY-Klausel  erscheinen.  Zudem

         darf  die   Projektion  nur  alphanumerische  Konstanten  und

         Aggregatfunktionen  anderer Spalten  enthalten,  die  in  der

         GROUP BY-Klausel nicht erscheinen müssen.

 

         In der GROUP BY-Klausel können auch mehrere Spalten angegeben

         werden. In diesem Fall wird die Gruppierung auf  Grund  aller

         angegebenen Spalten durchgeführt.

 

         Beispiel 7.29

 

         Gruppieren   Sie  die   Mitarbeiter  nach  Projektnummer  und

         Aufgabe.

 

                        SELECT pr_nr, aufgabe

                           FROM arbeiten

                           GROUP BY pr_nr, aufgabe;

 

         Das Ergebnis ist:

 

pr_nr

aufgabe             

p1   

Gruppenleiter       

p1   

Projektleiter       

p1   

Sachbearbeiter      

p1                        

 

p2   

Sachbearbeiter      

p2                        

 

p3   

Gruppenleiter       

p3   

Projektleiter       

p3   

Sachbearbeiter      

                                        

            (9 rows)

 

         Wie  aus  dem  Ergebnis  ersichtlich,  gibt  es  insgesamt  9

         Gruppen,  in denen  Projektnummer und Aufgabe unterschiedlich

         sind. Die beiden Gruppen, die mehr als eine Reihe beinhalten,

         sind

 

                p2       Sachberabeiter   25348, 28559

                p2       NULL             18316, 29346

 

         Die  Reihenfolge der  Spalten in  der  GROUP  BY-Klausel  muss

         nicht unbedingt der Reihenfolge der Spalten in der Projektion

         entsprechen.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.5        Aggregatfunktionen

 

 

         Zu den Aggregatfunktionen gehören folgende Funktionen:

 

                         - MIN;

                         - MAX;

                         - SUM;

                         - AVG     und

                         - COUNT.

 

         Alle Aggregatfunktionen  werden stets  auf  eine  Gruppe  von

         Reihen  angewendet,   wobei  die   Gruppe  auch  alle  Reihen

         einer  Tabelle  umfassen  kann.  Als  Ergebnis  liefert  jede

         Aggregatfunktion  einen   konstanten  Wert,   der  in   einer

         separaten Spalte im Ergebnis erscheint.

 

         Die   Aggregatfunktionen  können  in  einer  SELECT-Anweisung

         mit   oder  ohne   GROUP  BY-Klausel  erscheinen.  Falls  die

         SELECT-Anweisung  die GROUP  BY-Klausel nicht enthält, dürfen

         in der  Projektion nur die Spaltennamen angegeben werden, die

         als  Parameter der  Aggregatfunktion erscheinen. Deswegen ist

         das folgende Beispiel falsch:

 

         Beispiel 7.30

 

                         SELECT m_name, MIN(m_nr)

                            FROM mitarbeiter;

 

         Alle  Spaltennamen,  die nicht Parameter der Aggregatfunktion

         sind,  dürfen  in  der SELECT-Anweisung erscheinen, falls sie

         zur Gruppierung verwendet werden.

 

         Für alle Aggregatfunktionen kann zwischen den Angaben

 

                              - ALL      und

                              - DISTINCT

 

         gewählt  werden. ALL kennzeichnet alle Werte einer Spalte und

         stellt die  Voreinstellung dar.  Sie gilt  also,  wenn  weder

         ALL  noch DISTINCT angegeben sind. DISTINCT kennzeichnet alle

         unterschiedlichen Werte einer Spalte.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.5.1     Die Funktionen MIN und MAX

 

 

         Die Aggregatfunktionen  MIN und  MAX berechnen  den kleinsten

         bzw. den größten Datenwert einer Spalte.

 

         Beispiel 7.31

 

         Nennen Sie die kleinste Personalnummer eines Mitarbeiters.

 

                        SELECT MIN (m_nr)

                           FROM mitarbeiter;

 

         Das Ergebnis ist:

 

col1       

2581

                      

          (1 row)

 

         Das Ergebnis  dieses Beispiels ist nicht sehr aussagekräftig.

         Wir wissen  nicht, wie  der  Mitarbeiter  mit  der  kleinsten

         Personalnummer  heißt. Wie  schon gezeigt,  ist  die  direkte

         Angabe  des Mitarbeiternamens  in der  SELECT-Anweisung nicht

         erlaubt. Damit  der Name auch angegeben werden kann, muß eine

         Unterabfrage mit der Funktion MIN aufgebaut werden.

 

         Beispiel 7.32

 

         Nennen  Sie Personalnummer und Namen des Mitarbeiters mit der

         kleinsten Personalnummer.

 

                        SELECT m_nr, m_name

                           FROM mitarbeiter

                           WHERE m_nr =

                           (SELECT MIN(m_nr)

                               FROM mitarbeiter);

 

         Das Ergebnis ist:

 

m_nr    

m_name        

2581

Kaufmann      

                                  

         (1 row)

 

         Beispiel 7.33

 

         Finden  Sie  die  Personalnummer  des Projektleiters, der als

         letzter eingestellt wurde.

 

                        SELECT m_nr

                           FROM arbeiten

                           WHERE einst_dat =

                           (SELECT MAX(einst_dat)

                               FROM arbeiten

                               WHERE aufgabe = 'Projektleiter');

 

         Das Ergebnis ist:

 

m_nr   

2581

 

         (1 row)

 

         Die  Funktionen MIN  und MAX können auf alle alphanumerischen

         Werte angewendet werden. Bei den alphanumerischen Werten wird

         der kleinste  bzw. der  größte Wert  durch den  Vergleich der

         entsprechenden Zeichen nach ihrem Binärcode ermittelt.

 

         Die   Angabe  DISTINCT,  die  mehrfach  vorhandene  Werte  in

         einer   Spalte  entfernt,   hat  keine   Bedeutung  für   die

         Aggregatfunktionen  MIN und  MAX. Falls  MIN   bzw.  MAX  auf

         eine Spalte  mit NULL-Werten  angewendet  wird,  werden  alle

         NULL-Werte vor der Berechnung der Aggregatfunktion entfernt.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.5.2     Die Funktion SUM

 

 

         Die Aggregatfunktion  SUM berechnet die Summe der Werte einer

         Spalte. Die Spalte muß vom numerischen Datentyp sein.

 

         Beispiel 7.34

 

         Berechnen  sie   die  Summe  der  finanziellen  Mittel  aller

         Projekte.

 

                        SELECT SUM(mittel) AS summe

                           FROM projekt;

 

         Das Ergebnis ist:

 

summe         

401500.000

                       

         (1 row)

 

         Durch  die  Angabe  DISTINCT  werden die mehrfach vorhandenen

         Werte in der  betreffenden Spalte vor Verwendung der Funktion

         SUM eliminiert.  Falls  die  Funktion SUM auf eine Spalte mit

         NULL-Werten  angewendet  wird, werden vor der Berechnung  der

         Summe alle NULL-Werte entfernt.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.5.3     Die Funktion AVG

 

 

         Die Aggregatfunktion  AVG berechnet  das arithmetische Mittel

         der   Datenwerte  einer   Spalte.  Diese   Spalte  muß  einen

         numerischen Datentyp haben.

 

         Beispiel 7.35

 

         Berechnen  Sie  das arithmetische Mittel der Geldbeträge, die

         höher als 100.000 DM sind.

 

                        SELECT AVG(mittel) AS avg_mittel

                           FROM projekt

                           WHERE mittel > 100000;

 

         Das Ergebnis ist:

 

avg_mittel    

153250.000

                        

         (1 row)

 

         Durch  die Angabe  DISTINCT werden  alle mehrfach vorhandenen

         Werte  vor der  Berechnung des arithmetischen Mittels aus der

         betreffenden Spalte  eliminiert. Falls  die Funktion  AVG auf

         eine Spalte  mit NULL-Werten  angewendet  wird,  werden  alle

         NULL-Werte vor  der  Berechnung  des  arithmetischen  Mittels

         entfernt.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.5.4     Die Funktion COUNT

 

 

         Die Aggregatfunktion COUNT hat zwei verschiedene Formen. Die

         erste Form sieht wie folgt aus:

 

                        COUNT (DISTINCT sp_name)

 

         Sie  berechnet die Anzahl der Werte der Spalte sp_name, wobei

         alle mehrfach vorhandenen Werte nicht berücksichtigt  werden.

         DISTINCT muß in diesem Fall angegeben werden.

 

         Beispiel 7.36

 

         Finden  Sie  heraus,  wieviele verschiedene Aufgaben in jedem

         Projekt ausgeübt werden.

 

                    SELECT pr_nr, COUNT(DISTINCT aufgabe) AS anzahl

                           FROM arbeiten

                           GROUP BY pr_nr;

 

         Das Ergebnis ist:

 

pr_nr

anzahl      

p1             

3

p2             

1

p3             

3

                               

            (3 rows)

 

         Die  Funktion COUNT DISTINCT entfernt alle NULL-Werte aus der

         betreffenden Spalte.

 

         Die zweite Form der Funktion COUNT sieht folgendermaßen aus:

 

                          COUNT (*)

 

         Sie  berechnet  die Anzahl der Reihen.

 

 

         Beispiel 7.37

 

         Finden  Sie heraus,  wieviele Mitarbeiter  in  jedem  Projekt

         arbeiten.

 

 

                      SELECT pr_nr, COUNT(*) AS anzahl

                         FROM arbeiten

                         GROUP BY pr_nr;

 

         Das Ergebnis ist:

 

pr_nr

anzahl      

p1             

4

p2             

3

p3             

3

                               

            (3 rows)

 

         Im   Unterschied  zu  der  ersten  Form  der  COUNT-Funktion,

         berücksichtigt COUNT(*) auch Reihen mit NULL-Werten.

 

         Beispiel 7.38

 

         Gruppieren  Sie   die  Reihen   der  Tabelle   arbeiten  nach

         den vorhandenen  Aufgaben  und  finden  Sie  die  Anzahl  der

         Mitarbeiter der jeweiligen Aufgaben heraus.

 

                        SELECT aufgabe, COUNT(*) AS anz_aufg

                           FROM arbeiten

                           GROUP BY aufgabe;

 

         Das Ergebnis ist:

 

aufgabe         

anz_aufg  

Gruppenleiter            

2

Projektleiter            

2

Sachbearbeiter           

4

 

3

                                        

            (4 rows)

 

         Das  Ergebnis  der  Funktion  COUNT ist 0, falls sie auf eine

         leere Menge angewendet  wird (d.h. das Ergebnis liefert keine

         Reihe).

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.6        Die HAVING-Klausel

 

 

         Die  HAVING-Klausel  hat  dieselbe Funktion für die GROUP

         BYKlausel

                 wie  die  WHERE-Klausel für die SELECT-Anweisung. Mit

         anderen Worten:  Die  HAVING-Klausel  definiert die Bedingung

         nach der die  Reihengrupen  ausgewählt werden. Die allgemeine

         Form der HAVING-Klausel ist:

 

                          HAVING bedingung

 

         wobei  bedingung Aggregatfunktionen  und Konstanten enthalten

         darf.   Der  Ausdruck   in  bedingung  muß  je  Gruppe  stets

         einen einzigen  Wert als  Ergebnis  liefern.  In  der  Praxis

         werden  fast ausschließlich Vergleiche mit Aggregatfunktionen

         durchgeführt.

 

 

         Beispiel 7.39

 

         Nennen   Sie  alle  Projekte,  mit  denen  weniger  als  vier

         Mitarbeiter befasst sind.

 

                             SELECT pr_nr

                                FROM arbeiten

                                GROUP BY pr_nr

                                HAVING COUNT(*) < 4;

 

         Das Ergebnis ist:

 

pr_nr

p3   

                  

            (1 row)

 

         Alle Reihen der Tabelle arbeiten werden zunächst in bezug auf

         die  Spalte  pr_nr gruppiert. Die  Aggregatfunktion  COUNT(*)

         zählt alle Reihen jeder Gruppe und wählt die Gruppen aus, die

         weniger als vier Reihen beinhalten.

 

         Die  HAVING-Klausel  kann  auch  ohne  die  GROUP  BY-Klausel

         benutzt werden, obwohl dies in der Praxis selten vorkommt. In

         diesem Fall  wird die gesamte Tabelle als eine einzige Gruppe

         betrachtet.

 

Zurück zum Inhaltsverzeichnis

 

 

7.7        Die ORDER BY-Klausel

 

 

         Die ORDER  BY-Klausel definiert  die Reihenfolge  der Ausgabe

         aller  ausgewählten   Reihen  einer  SELECT-Anweisung.  Diese

         Klausel ist  optional  und  erscheint  immer  am  Ende  einer

         SELECT-Anweisung.  Die allgemeine  Form der  ORDER BY-Klausel

         ist:

 

                  ORDER BY {spalte | ganzzahl [ASC|DESC]},...

 

         spalte bezeichnet  eine Spalte,  mit der  der  Sortierbegriff

         definiert wird.  Mit der  Angabe von ganzzahl wird eine ganze

         Zahl definiert,  die die  Position einer Spalte kennzeichnet.

         ASC kennzeichnet  die aufsteigende  und DESC  die absteigende

         Sortierfolge.  Fehlt   diese  Angabe,   werden   die   Reihen

         aufsteigend sortiert.

 

         Beispiel 7.40

 

         Geben  Sie   Personalnummer,   Namen   und   Vornamen   aller

         Mitarbeiter, sortiert nach Personalnummern, an.

 

                        SELECT m_nr, m_name, m_vorname

                           FROM mitarbeiter

                           ORDER BY m_nr;

 

         Das Ergebnis ist:

 

m_nr    

m_name              

m_vorname      

2581

Kaufmann            

Brigitte       

9031

Meier               

Rainer         

10102

Huber               

Petra          

18316

Mueller             

Gabriele       

25348

Keller              

Hans            

28559

Mozer               

Sibille        

29346

Probst              

Andreas        

                                                      

        (7 rows)

 

         Die  in der  ORDER BY-Klausel  erscheinende Spalte muß in der

         Projektion  vorhanden sein.  Die Spalte  kann  auch  implizit

         durch  die Angabe  des Zeichens  "*" für  alle Spalten  einer

         Tabelle vorhanden sein.

 

         Der  Sortierbegriff kann, wie aus der Beschreibung der Syntax

         ersichtlich, mehrere Spalten beinhalten.

 

         Beispiel 7.41

 

         Geben   Sie  Namen,   Vornamen  und   Abteilungsnummer  aller

         Mitarbeiter an,  deren Personalnummer  kleiner als 20000 ist.

         Die Ausgabe  soll aufsteigend  nach Namen  und  Vornamen  der

         Mitarbeiter sortiert sein.

 

                        SELECT m_name, m_vorname, abt_nr

                           FROM mitarbeiter

                           WHERE m_nr < 20000

                           ORDER BY m_name, m_vorname;

 

         Das Ergebnis ist:

 

m_name    

m_vorname              

abt_nr      

Huber               

Petra               

a3    

Kaufmann            

Brigitte            

a2    

Meier               

Rainer              

a2    

Mueller             

Gabriele            

a1    

 

            (4 rows)

 

         Jede  Spalte  in  der  ORDER BY-Klausel kann durch eine ganze

         Zahl  ersetzt  werden, die die Position dieser Spalte in  der

         Projektion  definiert.  Im  letzten Beispiel könnte die ORDER

         BY-Klausel auch folgende Form haben:

 

                                 ORDER BY 1,2

 

         Die  Verwendung der ganzen Zahlen in der ORDER BY-Klausel ist

         die einzige Alternative, falls der Sortierbegriff durch  eine

         Aggregatfunktion  definiert  ist,  wie  das folgende Beispiel

         verdeutlicht.

 

         Beispiel 7.42

 

         Finden  Sie die Anzahl aller Mitarbeiter in jedem Projekt und

         sortieren Sie sie anschließend in absteigender Reihenfolge.

 

                        SELECT pr_nr, COUNT(*) AS anzahl

                           FROM arbeiten

                           GROUP BY pr_nr

                           ORDER BY 2 DESC;

 

         Das Ergebnis ist:

 

pr_nr

anzahl      

p1              

4

p2               

4

p3              

3

                               

            (3 rows)

 

         Bei  INGRES-SQL   werden  die  NULL-Werte  bei  aufsteigender

         Sortierfolge  nach allen anderen Werten, und bei absteigender

         Sortierfolge vor allen anderen Werten ausgegeben.

 

Zurück zum Inhaltsverzeichnis

 

 

 

7.8        Der Mengenoperator UNION

 

 

         Zusätzlich  zu   allen  Formen   der  SELECT-Anweisung,   die

         wir  bis  jetzt  beschrieben  haben,  ist  es  möglich,  zwei

         SELECT-Anweisung  mit   einem  Mengenoperator  zu  verbinden.

         INGRES-SQL unterstützt die Mengenoperation Vereinigung.

 

         Die Vereinigung zweier Datenmengen beinhaltet alle Daten, die

         entweder in  der ersten,  oder in  der zweiten oder in beiden

         Datenmengen  enthalten sind. Der Operator für die Vereinigung

         der Datenmengen heißt bei SQL UNION.

 

         Die allgemeine Form des Operators UNION ist:

 

              select_1 UNION [ALL] select_2 [UNION [ALL] select_3 ...]

 

         select_1  und select_2  kennzeichnen zwei SELECT-Anweisungen,

         die   der  Operator   UNION   verbindet.   Die   Angabe   ALL

         legt   fest,  daß   auch  mehrfach   vorhandene  Reihen   der

         Ergebnistabelle   ausgegeben  werden   sollen.  Diese  Angabe

         beim  Operator  UNION  hat  dieselbe  Bedeutung  wie  in  der

         Projektion   einer   SELECT-Anweisung.   Trotzdem   gibt   es

         einen  wichtigen  Unterschied.  In  der  Projektion  ist  die

         Angabe ALL  Voreinstellung,  d.h.  die  mehrfach  vorhandenen

         Reihen  der  Ergebnistabelle  einer  SELECT-Anweisung  werden

         ausgegeben,  falls weder  ALL noch  DISTINCT  angegeben  ist.

         Beim  UNION-Operator muß  man ALL explizit angeben, damit die

         mehrfach vorhandenen Reihen ausgegeben werden.

 

         Damit  wir auch  praktische Beispiele mit der Mengenoperation

         Vereinigung  zeigen können,  werden  wir  eine  neue  Tabelle

         mit_erweiter  erstellen. Die  Tabelle mit_erweiter entspricht

         der  Tabelle mitarbeiter  bis auf  eine zusätzliche  Spalte -

         wohnort. Die  Spalte wohnort  beschreibt  den  Wohnort  jedes

         Mitarbeiters.

 

         Die  Tabelle mit_erweiter  hat nach  der Erstellung  und  dem

         Einfügen der Daten folgende Form:

 

         mit_erweiter

        

m_nr   

m_name              

m_vorname           

abt_nr

wohnort

25348

Keller           

Hans             

a3     

Muenchen  

10102

Huber      

Petra     

a3    

Landshut  

18316

Mueller    

Gabriele  

a1    

Rosenheim 

29346

Probst           

Andreas          

a2    

Augsburg  

9031

Meier      

Rainer    

a2    

Augsburg  

2581

Kaufmann   

Brigitte  

a2    

Muenchen  

28559

Mozer            

Sibille          

a1    

Ulm       

                                                        

 

         Beispiel 7.43

 

         Finden  Sie  alle Wohnorte der Mitarbeiter und alle Standorte

         der Abteilungen.

 

                        SELECT wohnort

                           FROM mit_erweiter

                        UNION

                        SELECT stadt

                           FROM abteilung;

 

         Das Ergebnis ist:

 

wohnort            

Augsburg          

Landshut          

Muenchen          

Rosenheim         

Stuttgart         

Ulm               

                                 

              (6 rows)

 

         Damit  zwei   SELECT-Anweisungen   mit   dem   UNION-Operator

         verbunden  sein   können,  müssen   folgende  Voraussetzungen

         erfüllt sein:

 

              a) die Anzahl der Spalten in den beiden Projektionen muß

                 gleich sein;

              b) die   entsprechenden  Spalten  müssen  denselben  Typ

                 haben.

 

         Falls  die   Ausgabe  sortiert  sein  soll,  darf  die  ORDER

         BY-Klausel  nur in  der  letzten  SELECT-Anweisung  angegeben

         werden. Der  Sortierbegriff in  der ORDER  BY-Klausel darf in

         diesem  Fall nur  mit Hilfe  einer Ganzzahl definiert werden,

         die die Position der Spalte kennzeichnet.

 

         Beispiel 7.44

 

         Finden Sie  die Personalnummer  der Mitarbeiter, die entweder

         der Abteilung  a1 angehören  oder vor  dem  1.1.1988  in  das

         Projekt eingetreten  sind. Die Personalnummer sollen sortiert

         ausgegeben werden.

 

                        SELECT m_nr

                           FROM mitarbeiter

                           WHERE abt_nr = 'a1'

                        UNION

                        SELECT m_nr

                           FROM arbeiten

                           WHERE einst_dat < '01-jan-1988'

                           ORDER BY 1;

 

         Das Ergebnis ist:

 

m_nr          

18316

28559

29346

                    

         (3 rows)

 

         Der   UNION-Operator  ist   dem  Operator   OR  ähnlich.   In

         manchen  Fällen ist  es auch  möglich, die  Verbindung zweier

         SELECT-Anweisungen  mit   dem   UNION-Operator   durch   eine

         SELECT-Anweisung mit dem Operator OR zu ersetzen.

 

         Beispiel 7.45

 

         Finden  Sie  alle  Mitarbeiter, die entweder der Abteilung a1

         oder a2 oder aber beiden angehören.

 

                        SELECT m_nr, m_name, m_vorname

                           FROM mitarbeiter

                           WHERE abt_nr = 'a1'

                        UNION

                        SELECT m_nr, m_name, m_vorname

                           FROM mitarbeiter

                           WHERE abt_nr = 'a2';

 

         Das Ergebnis ist:

 

m_nr   

m_name              

m_vorname

2581

Kaufmann      

Brigitte      

9031

Meier         

Rainer        

18316

Mueller       

Gabriele      

28559

Mozer         

Sibille        

29346

Probst        

Andreas       

                                                  

          (5 rows)

 

         Dieselbe  Aufgabe  kann mit dem  OR-Operator einfacher gelöst

         werden:

 

         Beispiel 7.46

 

                        SELECT m_nr, m_name, m_vorname

                           FROM mitarbeiter

                           WHERE abt_nr = 'a1'

                           OR    abt_nr = 'a2';

 

         Der  UNION-Operator kann  nicht durch den OR-Operator ersetzt

         werden,  falls man  Reihen aus  zwei  verschiedenen  Tabellen

         wählt, wie es in den Beispielen 7.43 und 7.44 der Fall ist.

 

         Zusätzlich  zu  der  Operation  Vereinigung existieren in der

         Mengenlehre zwei weitere Operationen:

 

                       - Durchschnitt    und

                       - Differenz.

 

         Der  Durchschnitt  zweier  Datenmengen beinhaltet alle Daten,

         die sowohl in  der  ersten als auch in der zweiten Datenmenge

         enthalten sind.

 

         Die  Differenz  zweier Datenmengen beinhaltet alle Daten, die

         in  der  ersten Datenmenge enthalten sind und in der  zweiten

         nicht.

 

         INGRES-SQL unterstützt  diese zwei  Operationen nicht direkt.

         Trotzdem  ist es  möglich, die  beiden Operationen  mit Hilfe

         anderer Operatoren  zu ersetzen.  Der Durchschnitt kann durch

         den operator  EXISTS (siehe  Beispiel 8.21) und die Differenz

         durch  den Operator  NOT EXISTS (siehe Beispiel 8.22) ersetzt

         werden.

 

Zurück zum Inhaltsverzeichnis

 

 

 

Aufgaben

 

 

A.7.1   Wählen  Sie   alle  Reihen   der  Tabellen  arbeiten  und

                         mitarbeiter aus.

 

A.7.2   Finden Sie die Personalnummer aller Sachbearbeiter.

 

A.7.3   Finden  Sie  die  Personalnummer  der Mitarbeiter, die in

             Projekt p2 arbeiten und deren  Personalnummer kleiner als

             10000 ist.

 

A.7.4   Finden  Sie die Personalnummer der Mitarbeiter, die nicht

             im Jahr 1988 in ihr Projekt eingesetzt sind.

 

A.7.5   Finden  Sie  Personalnummer  aller  Mitarbeiter,  die  in

             Projekt  p1   eine  leitende   Aufgabe   (Gruppen-   oder

             Projektleiter) haben.

 

A.7.6   Finden  Sie  das  Einstellungsdatum  der  Mitarbeiter  in

             Projekt p2, deren Aufgabe noch nicht festgelegt ist.

 

A.7.7   Finden  Sie  Personalnummer,  Namen  und  Vornamen  aller

             Mitarbeiter, deren Name mit "M"  bzw. "H" anfängt und mit

             "er" endet.

 

A.7.8   Nennen  Sie  die Personalnummer aller Mitarbeiter,  deren

             Standort Stuttgart ist.

 

A.7.9   Finden  Sie  Namen und Vornamen aller Mitarbeiter, die am

             01-apr-1989 eingesetzt worden sind.

 

A.7.10 Gruppieren  Sie   alle  Abteilungen   auf   Grund   ihres

             Standortes.

 

A.7.11 Nennen Sie die grösste existierende Personalnummer.

 

A.7.12 Welche Aufgaben  werden von  mehr  als  zwei  Mitarbeiter

             ausgeübt?

 

A.7.13 Finden  Sie die  Personalnummer  aller  Mitarbeiter,  die

             entweder  Sachbearbeiter   sind  oder  der  Abteilung  a3

             angehören.

 

A.7.14 Warum ist folgende Aufgabe falsch

 

                        SELECT pr_name

                           FROM projekt

                           WHERE pr_nr =

                           (SELECT pr_nr

                              FROM arbeiten

                              WHERE aufgabe = 'Sachbearbeiter');

 

             Wie sollte diese Aufgabe richtig lauten?

 

Zurück zum Inhaltsverzeichnis