<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://mussswiki.idb.edu/iv1wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hans4mido</id>
	<title>IV1 - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://mussswiki.idb.edu/iv1wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hans4mido"/>
	<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1/Spezial:Beitr%C3%A4ge/Hans4mido"/>
	<updated>2026-06-03T00:40:57Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Digitale_Signatur&amp;diff=6122</id>
		<title>Digitale Signatur</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Digitale_Signatur&amp;diff=6122"/>
		<updated>2014-04-10T09:59:52Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Sicherheit|Sicherheit&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die digitale Signatur ist eine Errungenschaft und wichtigste Anwendung der asymmetrischen Verschlüsselung. Sie dient als Basis für das Unterzeichnen (Unterschreiben) digitaler Dokumente. Sogenannte Zertifizierungsstellen sind erforderlich, um die Identität des Schlüsselinhabers zu bestätigen. Zertifiziert werden heute aber vor allem Internetdienste mit sensiblen oder ökonomisch wertvollen Daten, wie z. B. die Internetdienste der Banken.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Zertifikat ==&lt;br /&gt;
&lt;br /&gt;
Während zur Sicherstellung der Authentizität des Empfängers dessen geheimer Entschlüsselungs-Schlüssel Garant für die korrekte Zustellung ist (jeder potentielle Empfänger wird darauf bedacht sein, dass sein geheimer Schlüssel nicht in die Hände Unberechtigter gerät), stellt sich bei der Authentizität des Absenders das Problem der Zuordnung zwischen veröffentlichtem Entschlüsselungs-Schlüssel und der Identität des vermeintlichen Senders. Unredliche AbsenderInnen signierter Dokumente könnte vortäuschen, im Namen fremder Personen zu handeln (zu schreiben), indem der Unredliche einen Entschlüsselungs-Schlüssel kommuniziert, der jedoch nicht mit seiner wahren Identität übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert die Notwendigkeit eines Zertifikates (der grün gefärbte &amp;quot;Haken&amp;quot; in der nachfolgenden Abbildung), welches bestätigt, dass der mitgeteilte bzw. veröffentlichte Entschlüsselungs-Schlüssel auch zur redlichen AbsenderIn, die auch InhaberIn des entsprechenden, geheimen Verschlüsselungs-Schlüssels ist, gehört.&lt;br /&gt;
&lt;br /&gt;
[[Datei:zertifikat.gif]]&lt;br /&gt;
&lt;br /&gt;
Die Organisation der Ausstellung von Zertifikaten unterliegt praktizierten bzw. vereinbarten Methoden, von der Kundmachung in privaten Medien (z. B. über Visitkarten) bis hin zu gesetzlich ermächtigten oder global anerkannten Zertifizierungsstellen.&lt;br /&gt;
&lt;br /&gt;
Beispiele für national bzw. international anerkannte Zertifizierungsstellen sind:&lt;br /&gt;
&lt;br /&gt;
* A-Trust &amp;lt;ref&amp;gt;http://www.a-trust.at/&amp;lt;/ref&amp;gt;&lt;br /&gt;
* A-Cert &amp;lt;ref&amp;gt;http://www.a-cert.at&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Verisign &amp;lt;ref&amp;gt;http://www.verisign.com/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zertifikate werden aber nicht nur für Verifizierung einzelner Mitteilungen (E-Mails) ausgestellt, sondern auch für das Informationsangebot ganzer Websites oder Internet-Dienste (z. B. Mailservice) verwendet. Die Zertifikate unterstützen in diesem Fall die Frage nach der Echtheit des genutzten Dienstes. Nachgebaute Websites von Banken, die den Kunden veranlassen seine Passwörter Preis zu geben, können erheblichen Schaden verursachen. Die Verwaltung und Überprüfung der Zertifikate von Websites oder Maildienste werden von der Systemsoftware in Verbindung mit dem verwendeten Browser oder Mail-Clients meist ohne Eingreifen des Benutzers durchgeführt. Nur im Falle von Ausnahmen wird der Benutzer auf den Umstand aufmerksam gemacht und ggfs. zur Entscheidung über Abbruch oder Weiterarbeit aufgefordert.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.buergerkarte.at/de/index.html Die österreichische Bürgerkarte]&lt;br /&gt;
* [http://www.a-sit.at/de/signatur/index.php Signatur]&lt;br /&gt;
* [http://www.ihr-sicherer-etresor.at/tag/digitale-signatur/ Digitaler Datensafe]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (21.9.2009), Digitale Signatur#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Digitale_Signatur&amp;diff=6121</id>
		<title>Digitale Signatur</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Digitale_Signatur&amp;diff=6121"/>
		<updated>2014-04-10T09:57:37Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Sicherheit|Sicherheit&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die digitale Signatur ist eine Errungenschaft und wichtigste Anwendung der asymmetrischen Verschlüsselung. Sie dient als Basis für das Unterzeichnen (Unterschreiben) digitaler Dokumente. Sogenannte Zertifizierungsstellen sind erforderlich, um die Identität des Schlüsselinhabers zu bestätigen. Zertifiziert werden heute aber vor allem Internetdienste mit sensiblen oder ökonomisch wertvollen Daten, wie z. B. die Internetdienste der Banken.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Zertifikat ==&lt;br /&gt;
&lt;br /&gt;
Während zur Sicherstellung der Authentizität des Empfängers dessen geheimer Entschlüsselungs-Schlüssel Garant für die korrekte Zustellung ist (jeder potentielle Empfänger wird darauf bedacht sein, dass sein geheimer Schlüssel nicht in die Hände Unberechtigter gerät), stellt sich bei der Authentizität des Absenders das Problem der Zuordnung zwischen veröffentlichtem Entschlüsselungs-Schlüssel und der Identität des vermeintlichen Senders. Unredliche AbsenderInnen signierter Dokumente könnte vortäuschen, im Namen fremder Personen zu handeln (zu schreiben), indem der Unredliche einen Entschlüsselungs-Schlüssel kommuniziert, der jedoch nicht mit seiner wahren Identität übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert die Notwendigkeit eines Zertifikates (der grün gefärbte &amp;quot;Haken&amp;quot; in der nachfolgenden Abbildung), welches bestätigt, dass der mitgeteilte bzw. veröffentlichte Entschlüsselungs-Schlüssel auch zur redlichen AbsenderIn, die auch InhaberIn des entsprechenden, geheimen Verschlüsselungs-Schlüssels ist, gehört.&lt;br /&gt;
&lt;br /&gt;
[[Datei:zertifikat.gif]]&lt;br /&gt;
&lt;br /&gt;
Die Organisation der Ausstellung von Zertifikaten unterliegt praktizierten bzw. vereinbarten Methoden, von der Kundmachung in privaten Medien (z. B. über Visitkarten) bis hin zu gesetzlich ermächtigten oder global anerkannten Zertifizierungsstellen.&lt;br /&gt;
&lt;br /&gt;
Beispiele für national bzw. international anerkannte Zertifizierungsstellen sind:&lt;br /&gt;
&lt;br /&gt;
* A-Trust &amp;lt;ref&amp;gt;http://www.a-trust.at/&amp;lt;/ref&amp;gt;&lt;br /&gt;
* A-Cert &amp;lt;ref&amp;gt;http://http://www.a-cert.at&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Verisign &amp;lt;ref&amp;gt;http://www.verisign.com/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zertifikate werden aber nicht nur für Verifizierung einzelner Mitteilungen (E-Mails) ausgestellt, sondern auch für das Informationsangebot ganzer Websites oder Internet-Dienste (z. B. Mailservice) verwendet. Die Zertifikate unterstützen in diesem Fall die Frage nach der Echtheit des genutzten Dienstes. Nachgebaute Websites von Banken, die den Kunden veranlassen seine Passwörter Preis zu geben, können erheblichen Schaden verursachen. Die Verwaltung und Überprüfung der Zertifikate von Websites oder Maildienste werden von der Systemsoftware in Verbindung mit dem verwendeten Browser oder Mail-Clients meist ohne Eingreifen des Benutzers durchgeführt. Nur im Falle von Ausnahmen wird der Benutzer auf den Umstand aufmerksam gemacht und ggfs. zur Entscheidung über Abbruch oder Weiterarbeit aufgefordert.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.buergerkarte.at/de/index.html Die österreichische Bürgerkarte]&lt;br /&gt;
* [http://www.a-sit.at/de/signatur/index.php Signatur]&lt;br /&gt;
* [http://www.ihr-sicherer-etresor.at/tag/digitale-signatur/ Digitaler Datensafe]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (21.9.2009), Digitale Signatur#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Normalformen&amp;diff=5898</id>
		<title>Normalformen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Normalformen&amp;diff=5898"/>
		<updated>2013-02-25T21:16:41Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Dritte Normalform: Vermeidung von transitiven Abhängigkeiten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Der Aufbau relationaler Datenbanken, ersichtlich in den Inhalten ihrer Tabellen und deren Beziehungen untereinander, zielt in erster Linie auf die Vermeidung von Redundanzen ab. Sogenannte Normalformen können als Gesetze zur Konstruktion von Tabellen betrachtet werden, deren Einhaltung zur weitgehenden Vermeidung von Redundanzen führen. Die Normalformen sind Gegenstand des folgenden Lernschrittes.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Sinn der Normalisierung==&lt;br /&gt;
&lt;br /&gt;
Bei der Aufgabe, eine Datenbank anzulegen, wird man mit mehreren Fragen konfrontiert.&lt;br /&gt;
* Wie viele Tabellen sind sinnvoll?&lt;br /&gt;
* Was soll darin dargestellt werden?&lt;br /&gt;
* Wie viele Spalten sollen in welcher Tabelle angelegt werden?&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf diese Fragen gibt mitunter die sogenannte &#039;&#039;&#039;Normalisierung&#039;&#039;&#039;. Mit Hilfe der Regeln der Normalisierung wird es möglich, die Datenbank ideal zu strukturieren. Dadurch werden &#039;&#039;&#039;Redundanzen&#039;&#039;&#039; vermieden: Diese erfordern nämlich nicht nur einen größeren Speicherbedarf, sondern führen auch zu einer erhöhten Fehleranfälligkeit, beispielsweise bei Wartungstätigkeiten. Sollen Daten, die an mehr als einem Speicherort vorhanden sind, geändert werden, müssen diese Änderungen an allen Speicherorten auf exakt die gleiche Art und Weise vorgenommen werden. So ist beispielsweise die Änderung einer Kundenandresse wesentlich einfacher, wenn die betreffenden Daten nur in der Tabelle &#039;&#039;Kunde&#039;&#039; gespeichert sind und nicht auch noch an anderen Orten innerhalb der Datenbank.&lt;br /&gt;
&lt;br /&gt;
== Normalisieren der Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Überführung der Objektklassen in Tabellen sind diese daraufhin zu prüfen, ob sie Abhängigkeiten der Felder untereinander bzw. Redundanzen aufweisen. Normalisiert wird, indem man schrittweise überprüft, ob die gebildeten Tabellen den Bedingungen der Normalformen entsprechen. Im Verlauf dieses Normalisierungsprozesses kommt es zu einer Reduzierung der Redundanzen, parallel dazu jedoch auch zu einer Vermehrung der Anzahl der Tabellen. Immer dann, wenn Redundanzen entdeckt werden, führt dies zur Bildung neuer Tabellen, die über die Schlüsselfelder miteinander verbunden werden (siehe [[Beziehungen in Datenbanken]]). Die Anpassung der Tabellen an die Normalformen dient auch der mengentheoretischen Grundlage von SQL. Die Anwendung von drei Normalformen wird aus Gründen des Antwortzeitverhaltens der Datenbank empfohlen. Die Datenbanktheorie unterscheidet zwar weitere Normalformen, diese werden aber in der Praxis nur selten angewendet.&lt;br /&gt;
&lt;br /&gt;
== Erste Normalform: Entfernen von Wiederholgruppen ==&lt;br /&gt;
&lt;br /&gt;
Jedes Feld darf im Datensatz &#039;&#039;&#039;nur einmal&#039;&#039;&#039; vorkommen. Gibt es mehrere Felder vom &#039;&#039;&#039;gleichen Typ&#039;&#039;&#039;, so müssen diese in einer &#039;&#039;&#039;eigenen Tabelle&#039;&#039;&#039; gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Die Überführung der Objektklasse &#039;&#039;Auftrag&#039;&#039; in eine Tabelle könnte der verbalen Beschreibung des Geschäftsmodells entsprechend „Jeder Auftrag kann mehrere Bücher enthalten, die jeweils in beliebiger Menge geordert werden können“ bzw. in Anlehnung an das ER-Diagramm folgende Struktur aufweisen:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Auftrag&#039;&#039; (Nr, Kundennummer, Datum, Positionsnummer, Buchnummer, Menge, Positionsnummer, Buchnummer, Menge, ...)&lt;br /&gt;
&lt;br /&gt;
Da ein Auftrag in der Regel mehrere unterschiedliche Bücher in unterschiedlichen Mengen enthält, kommen die Felder &#039;&#039;Buchnummer&#039;&#039; und &#039;&#039;Menge&#039;&#039; mehrfach vor, was der ersten Normalform widerspricht. Die Konsequenz daraus ist die Auslagerung der Wiederholgruppen in eine eigene Tabelle &#039;&#039;Auftragspos&#039;&#039; (abgeleitet von Auftragsposition) und die Verbindung der Tabellen über entsprechende Schlüsselfelder.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell_3.gif]]&lt;br /&gt;
&lt;br /&gt;
Das Feld &#039;&#039;Nr&#039;&#039; in der Tabelle &#039;&#039;Auftrag&#039;&#039; (&#039;&#039;Auftrag.Nr&#039;&#039;) ist das Schlüsselfeld der Tabelle &#039;&#039;Auftrag&#039;&#039; und wird daher mit dem Feld &#039;&#039;Auftragsnummer&#039;&#039; der Tabelle Auftragsposition verbunden. Die Namen der beiden Felder unterscheiden sich zwar, aber der Inhalt ist in beiden Fällen ident. Hier zeigt sich eine unvermeidbare Redundanz in relationalen Datenbanken, weshalb man auch von &#039;&#039;&#039;kontrollierter Redundanz&#039;&#039;&#039; und nicht von redundanzfrei spricht.&lt;br /&gt;
&lt;br /&gt;
Für die Erfüllung der im Geschäftsmodell beschriebenen Aufgaben (z. B. Rechnungslegung) sind detaillierte Daten über die Bücher (z. B. der Preis) erforderlich. Wie auch aus dem ER-Diagramm ersichtlich ist, gibt es eine Verbindung zwischen der Tabelle &#039;&#039;Auftrag&#039;&#039; und der Tabelle &#039;&#039;Buch&#039;&#039; über die neu gebildete Tabelle &#039;&#039;Auftragspos&#039;&#039;. Die Notwendigkeit zur Neubildung einer Tabelle zwischen &#039;&#039;Auftrag&#039;&#039; und &#039;&#039;Buch&#039;&#039; ist auch aus ihrer m:n-Beziehung ableitbar.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell_4.gif]]&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Auftragspos.Nr&#039;&#039; der Tabelle &#039;&#039;Auftragspos&#039;&#039; ist als Primärschlüssel nicht zu gebrauchen, sie dient lediglich der Kennzeichnung der einzelnen Auftragspositionen eines Auftrages, z. B. zum Zwecke der Reihung auf Lieferscheinen oder Rechnungen. Der Primärschlüssel der Tabelle &#039;&#039;Auftragspos&#039;&#039; setzt sich vielmehr aus den Feldern &#039;&#039;Auftragspos.Auftragsnummer&#039;&#039; und &#039;&#039;Auftragspos.Buchnummer&#039;&#039; zusammen. Es handelt sich um einen Kombinationsschlüssel. Auch dieses Auftreten von Kombinationsschlüsseln ist für die normalformengerechte Auflösung von m:n-Beziehungen typisch.&lt;br /&gt;
&lt;br /&gt;
== Zweite Normalform: Entfernen von Attributen, die nur von einigen der identifizierenden Attribute abhängen ==&lt;br /&gt;
&lt;br /&gt;
Zu den Bedingungen der 1. Normalform gilt zusätzlich: In Relationen mit einem Kombinationsschlüssel muss jedes Feld vom gesamten Kombinationsschlüssel abhängen. Felder, die nur von einem Teil des Schlüssels abhängen, werden mit diesem als Schlüssel in einer eigenen Relation gespeichert.&lt;br /&gt;
&lt;br /&gt;
Die Tabelle &#039;&#039;Auftragspos&#039;&#039; besitzt einen Kombinationsschlüssel, wie in der Abbildung zuvor ersichtlich ist. Da aber der Entwurf der vorliegenden Datenbank mit der  Erstellung eines ER-Diagramms begonnen hat, befinden sich in dieser Tabelle keine Felder, die der 2. Normalform widersprechen. Es können jedoch in Frage kommende Erweiterungen der gegenständlichen Tabelle als Erläuterung am Beispiel herangezogen werden.&lt;br /&gt;
&lt;br /&gt;
Geht man z. B. davon aus, dass nicht alle Positionen eines Auftrags sofort geliefert werden können und sind Teillieferungen geplant, so wäre das Datum der Auslieferung (wohlgemerkt der gesamten bestellten Menge, keine Teilmengen) ein Feld, welches die Bedingung der 2. Normalform erfüllte.&lt;br /&gt;
&lt;br /&gt;
Für den Fall, dass Preisnachlässe in Form von Rabatten gewährt werden, könnte ein weiteres Feld mit der Bezeichnung &#039;&#039;Rabatt&#039;&#039; angefügt werden. Diese Art der Gewährung von Rabatten bedeutet, dass der Preisnachlass einmalig und nur für ein bestimmtes Produkt gewährt wird. Ebenso könnte ein Feld &#039;&#039;Rabatt&#039;&#039; der Tabelle &#039;&#039;Buch&#039;&#039;, der Tabelle &#039;&#039;Kunde&#039;&#039; oder der Tabelle &#039;&#039;Auftrag&#039;&#039; angefügt werden, ohne die Normalformen zu verletzen. Die Bedeutung der alternativen Platzierung ist jedoch sehr unterschiedlich. Das Feld &#039;&#039;Rabatt&#039;&#039; in der Tabelle &#039;&#039;Kunde&#039;&#039; bewirkt, dass alle Einkäufe des jeweiligen Kunden mit einem Preisnachlass versehen werden, während das besagte Feld in der Tabelle &#039;&#039;Buch&#039;&#039; Preisnachlässe für alle Kunden nach sich zieht.&lt;br /&gt;
&lt;br /&gt;
Diese Variationsmöglichkeiten zeigen deutlich, dass die formale Korrektheit einer relationalen Datenbank nicht ohne das zugrundeliegende Geschäftsmodell bzw. deren Prozesse überprüft werden kann.&lt;br /&gt;
&lt;br /&gt;
== Dritte Normalform: Vermeidung von transitiven Abhängigkeiten ==&lt;br /&gt;
&lt;br /&gt;
Zu den Bedingungen der 2. Normalform gilt zusätzlich: Felder, die nicht Teil des Schlüssels sind, dürfen nicht untereinander abhängig sein; ist dies der Fall, so müssen diese in einer eigenen Relation gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Gemäß dem angestellten ER-Diagramm fehlen dem Datenmodell noch die entsprechenden Tabellen für die Kunden und Verlage. Beide enthalten Felder für die Adresse, nämlich &#039;&#039;Plz&#039;&#039;, &#039;&#039;Ort&#039;&#039; und &#039;&#039;Straße&#039;&#039; (Letzteres enthält auch die Hausnummer).&lt;br /&gt;
&lt;br /&gt;
Berücksichtigt man die Zustellbezirke der Post, so kann festgestellt werden, dass jeder Postleitzahl eindeutig ein Zustellbezirk (zur zeitweiligen Verwirrung auch &amp;quot;Ort&amp;quot; genannt) zugeordnet werden kann. Das Feld &#039;&#039;Ort&#039;&#039; hängt demnach vom Feld &#039;&#039;Plz&#039;&#039; ab und muss ausgelagert werden.&lt;br /&gt;
Die ohne Berücksichtigung der 3. Normalform also falsch konstruierte Tabellen wären:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Verlag&#039;&#039; (Kurzbezeichnung, Name, Kundennummer, Strasse, Plz, Ort)&lt;br /&gt;
* &#039;&#039;Kunde&#039;&#039; (Nr, Vorname, Nachname, Strasse, Plz, Ort)&lt;br /&gt;
&lt;br /&gt;
Adressen werden des Feldes &#039;&#039;Ort&#039;&#039; entledigt und es entsteht eine neue Tabelle mit der Bezeichnung &#039;&#039;PLZ&#039;&#039; und den Spalten Plz, Ort und Region.&lt;br /&gt;
&lt;br /&gt;
Das endgültige, den Normalformen 1 bis 3 unterworfene Datenmodell zeigt folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
R. Elmasri, S. B. Navathe: Grundlagen von Datenbanksystemen. Ausgabe Grundstudium. Pearson Studium 2005&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.tinohempel.de/info/info/datenbank/normalisierung.htm Richard-Wossidlo-Gymnasium Ribnitz-Damgarten]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), Normalformen (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Normalformen&amp;diff=5897</id>
		<title>Normalformen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Normalformen&amp;diff=5897"/>
		<updated>2013-02-25T21:13:38Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Dritte Normalform: Vermeidung von transitiven Abhängigkeiten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Der Aufbau relationaler Datenbanken, ersichtlich in den Inhalten ihrer Tabellen und deren Beziehungen untereinander, zielt in erster Linie auf die Vermeidung von Redundanzen ab. Sogenannte Normalformen können als Gesetze zur Konstruktion von Tabellen betrachtet werden, deren Einhaltung zur weitgehenden Vermeidung von Redundanzen führen. Die Normalformen sind Gegenstand des folgenden Lernschrittes.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Sinn der Normalisierung==&lt;br /&gt;
&lt;br /&gt;
Bei der Aufgabe, eine Datenbank anzulegen, wird man mit mehreren Fragen konfrontiert.&lt;br /&gt;
* Wie viele Tabellen sind sinnvoll?&lt;br /&gt;
* Was soll darin dargestellt werden?&lt;br /&gt;
* Wie viele Spalten sollen in welcher Tabelle angelegt werden?&lt;br /&gt;
&lt;br /&gt;
Die Antwort auf diese Fragen gibt mitunter die sogenannte &#039;&#039;&#039;Normalisierung&#039;&#039;&#039;. Mit Hilfe der Regeln der Normalisierung wird es möglich, die Datenbank ideal zu strukturieren. Dadurch werden &#039;&#039;&#039;Redundanzen&#039;&#039;&#039; vermieden: Diese erfordern nämlich nicht nur einen größeren Speicherbedarf, sondern führen auch zu einer erhöhten Fehleranfälligkeit, beispielsweise bei Wartungstätigkeiten. Sollen Daten, die an mehr als einem Speicherort vorhanden sind, geändert werden, müssen diese Änderungen an allen Speicherorten auf exakt die gleiche Art und Weise vorgenommen werden. So ist beispielsweise die Änderung einer Kundenandresse wesentlich einfacher, wenn die betreffenden Daten nur in der Tabelle &#039;&#039;Kunde&#039;&#039; gespeichert sind und nicht auch noch an anderen Orten innerhalb der Datenbank.&lt;br /&gt;
&lt;br /&gt;
== Normalisieren der Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Überführung der Objektklassen in Tabellen sind diese daraufhin zu prüfen, ob sie Abhängigkeiten der Felder untereinander bzw. Redundanzen aufweisen. Normalisiert wird, indem man schrittweise überprüft, ob die gebildeten Tabellen den Bedingungen der Normalformen entsprechen. Im Verlauf dieses Normalisierungsprozesses kommt es zu einer Reduzierung der Redundanzen, parallel dazu jedoch auch zu einer Vermehrung der Anzahl der Tabellen. Immer dann, wenn Redundanzen entdeckt werden, führt dies zur Bildung neuer Tabellen, die über die Schlüsselfelder miteinander verbunden werden (siehe [[Beziehungen in Datenbanken]]). Die Anpassung der Tabellen an die Normalformen dient auch der mengentheoretischen Grundlage von SQL. Die Anwendung von drei Normalformen wird aus Gründen des Antwortzeitverhaltens der Datenbank empfohlen. Die Datenbanktheorie unterscheidet zwar weitere Normalformen, diese werden aber in der Praxis nur selten angewendet.&lt;br /&gt;
&lt;br /&gt;
== Erste Normalform: Entfernen von Wiederholgruppen ==&lt;br /&gt;
&lt;br /&gt;
Jedes Feld darf im Datensatz &#039;&#039;&#039;nur einmal&#039;&#039;&#039; vorkommen. Gibt es mehrere Felder vom &#039;&#039;&#039;gleichen Typ&#039;&#039;&#039;, so müssen diese in einer &#039;&#039;&#039;eigenen Tabelle&#039;&#039;&#039; gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Die Überführung der Objektklasse &#039;&#039;Auftrag&#039;&#039; in eine Tabelle könnte der verbalen Beschreibung des Geschäftsmodells entsprechend „Jeder Auftrag kann mehrere Bücher enthalten, die jeweils in beliebiger Menge geordert werden können“ bzw. in Anlehnung an das ER-Diagramm folgende Struktur aufweisen:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Auftrag&#039;&#039; (Nr, Kundennummer, Datum, Positionsnummer, Buchnummer, Menge, Positionsnummer, Buchnummer, Menge, ...)&lt;br /&gt;
&lt;br /&gt;
Da ein Auftrag in der Regel mehrere unterschiedliche Bücher in unterschiedlichen Mengen enthält, kommen die Felder &#039;&#039;Buchnummer&#039;&#039; und &#039;&#039;Menge&#039;&#039; mehrfach vor, was der ersten Normalform widerspricht. Die Konsequenz daraus ist die Auslagerung der Wiederholgruppen in eine eigene Tabelle &#039;&#039;Auftragspos&#039;&#039; (abgeleitet von Auftragsposition) und die Verbindung der Tabellen über entsprechende Schlüsselfelder.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell_3.gif]]&lt;br /&gt;
&lt;br /&gt;
Das Feld &#039;&#039;Nr&#039;&#039; in der Tabelle &#039;&#039;Auftrag&#039;&#039; (&#039;&#039;Auftrag.Nr&#039;&#039;) ist das Schlüsselfeld der Tabelle &#039;&#039;Auftrag&#039;&#039; und wird daher mit dem Feld &#039;&#039;Auftragsnummer&#039;&#039; der Tabelle Auftragsposition verbunden. Die Namen der beiden Felder unterscheiden sich zwar, aber der Inhalt ist in beiden Fällen ident. Hier zeigt sich eine unvermeidbare Redundanz in relationalen Datenbanken, weshalb man auch von &#039;&#039;&#039;kontrollierter Redundanz&#039;&#039;&#039; und nicht von redundanzfrei spricht.&lt;br /&gt;
&lt;br /&gt;
Für die Erfüllung der im Geschäftsmodell beschriebenen Aufgaben (z. B. Rechnungslegung) sind detaillierte Daten über die Bücher (z. B. der Preis) erforderlich. Wie auch aus dem ER-Diagramm ersichtlich ist, gibt es eine Verbindung zwischen der Tabelle &#039;&#039;Auftrag&#039;&#039; und der Tabelle &#039;&#039;Buch&#039;&#039; über die neu gebildete Tabelle &#039;&#039;Auftragspos&#039;&#039;. Die Notwendigkeit zur Neubildung einer Tabelle zwischen &#039;&#039;Auftrag&#039;&#039; und &#039;&#039;Buch&#039;&#039; ist auch aus ihrer m:n-Beziehung ableitbar.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell_4.gif]]&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Auftragspos.Nr&#039;&#039; der Tabelle &#039;&#039;Auftragspos&#039;&#039; ist als Primärschlüssel nicht zu gebrauchen, sie dient lediglich der Kennzeichnung der einzelnen Auftragspositionen eines Auftrages, z. B. zum Zwecke der Reihung auf Lieferscheinen oder Rechnungen. Der Primärschlüssel der Tabelle &#039;&#039;Auftragspos&#039;&#039; setzt sich vielmehr aus den Feldern &#039;&#039;Auftragspos.Auftragsnummer&#039;&#039; und &#039;&#039;Auftragspos.Buchnummer&#039;&#039; zusammen. Es handelt sich um einen Kombinationsschlüssel. Auch dieses Auftreten von Kombinationsschlüsseln ist für die normalformengerechte Auflösung von m:n-Beziehungen typisch.&lt;br /&gt;
&lt;br /&gt;
== Zweite Normalform: Entfernen von Attributen, die nur von einigen der identifizierenden Attribute abhängen ==&lt;br /&gt;
&lt;br /&gt;
Zu den Bedingungen der 1. Normalform gilt zusätzlich: In Relationen mit einem Kombinationsschlüssel muss jedes Feld vom gesamten Kombinationsschlüssel abhängen. Felder, die nur von einem Teil des Schlüssels abhängen, werden mit diesem als Schlüssel in einer eigenen Relation gespeichert.&lt;br /&gt;
&lt;br /&gt;
Die Tabelle &#039;&#039;Auftragspos&#039;&#039; besitzt einen Kombinationsschlüssel, wie in der Abbildung zuvor ersichtlich ist. Da aber der Entwurf der vorliegenden Datenbank mit der  Erstellung eines ER-Diagramms begonnen hat, befinden sich in dieser Tabelle keine Felder, die der 2. Normalform widersprechen. Es können jedoch in Frage kommende Erweiterungen der gegenständlichen Tabelle als Erläuterung am Beispiel herangezogen werden.&lt;br /&gt;
&lt;br /&gt;
Geht man z. B. davon aus, dass nicht alle Positionen eines Auftrags sofort geliefert werden können und sind Teillieferungen geplant, so wäre das Datum der Auslieferung (wohlgemerkt der gesamten bestellten Menge, keine Teilmengen) ein Feld, welches die Bedingung der 2. Normalform erfüllte.&lt;br /&gt;
&lt;br /&gt;
Für den Fall, dass Preisnachlässe in Form von Rabatten gewährt werden, könnte ein weiteres Feld mit der Bezeichnung &#039;&#039;Rabatt&#039;&#039; angefügt werden. Diese Art der Gewährung von Rabatten bedeutet, dass der Preisnachlass einmalig und nur für ein bestimmtes Produkt gewährt wird. Ebenso könnte ein Feld &#039;&#039;Rabatt&#039;&#039; der Tabelle &#039;&#039;Buch&#039;&#039;, der Tabelle &#039;&#039;Kunde&#039;&#039; oder der Tabelle &#039;&#039;Auftrag&#039;&#039; angefügt werden, ohne die Normalformen zu verletzen. Die Bedeutung der alternativen Platzierung ist jedoch sehr unterschiedlich. Das Feld &#039;&#039;Rabatt&#039;&#039; in der Tabelle &#039;&#039;Kunde&#039;&#039; bewirkt, dass alle Einkäufe des jeweiligen Kunden mit einem Preisnachlass versehen werden, während das besagte Feld in der Tabelle &#039;&#039;Buch&#039;&#039; Preisnachlässe für alle Kunden nach sich zieht.&lt;br /&gt;
&lt;br /&gt;
Diese Variationsmöglichkeiten zeigen deutlich, dass die formale Korrektheit einer relationalen Datenbank nicht ohne das zugrundeliegende Geschäftsmodell bzw. deren Prozesse überprüft werden kann.&lt;br /&gt;
&lt;br /&gt;
== Dritte Normalform: Vermeidung von transitiven Abhängigkeiten ==&lt;br /&gt;
&lt;br /&gt;
Zu den Bedingungen der 2. Normalform gilt zusätzlich: Felder, die nicht Teil des Schlüssels sind, dürfen nicht untereinander abhängig sein; ist dies der Fall, so müssen diese in einer eigenen Relation gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Gemäß dem angestellten ER-Diagramm fehlen dem Datenmodell noch die entsprechenden Tabellen für die Kunden und Verlage. Beide enthalten Felder für die Adresse, nämlich &#039;&#039;Plz&#039;&#039;, &#039;&#039;Ort&#039;&#039; und &#039;&#039;Straße&#039;&#039; (Letzteres enthält auch die Hausnummer).&lt;br /&gt;
&lt;br /&gt;
Berücksichtigt man die Zustellbezirke der Post, so kann festgestellt werden, dass jeder Postleitzahl eindeutig ein Zustellbezirk (zur zeitweiligen Verwirrung auch &amp;quot;Ort&amp;quot; genannt) zugeordnet werden kann. Das Feld &#039;&#039;Ort&#039;&#039; hängt demnach vom Feld &#039;&#039;Plz&#039;&#039; ab und muss ausgelagert werden.&lt;br /&gt;
Die ohne Berücksichtigung der 3. Normalform also falsch abgeleitete Tabellen wären:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Verlag&#039;&#039; (Kurzbezeichnung, Name, Kundennummer, Strasse, Plz, Ort)&lt;br /&gt;
* &#039;&#039;Kunde&#039;&#039; (Nr, Vorname, Nachname, Strasse, Plz, Ort)&lt;br /&gt;
&lt;br /&gt;
Adressen werden des Feldes &#039;&#039;Ort&#039;&#039; entledigt und es entsteht eine neue Tabelle mit der Bezeichnung &#039;&#039;PLZ&#039;&#039; mit den Spalten PLZ, Ort und Region.&lt;br /&gt;
&lt;br /&gt;
Das endgültige, den Normalformen 1 bis 3 unterworfene Datenmodell zeigt folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
R. Elmasri, S. B. Navathe: Grundlagen von Datenbanksystemen. Ausgabe Grundstudium. Pearson Studium 2005&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.tinohempel.de/info/info/datenbank/normalisierung.htm Richard-Wossidlo-Gymnasium Ribnitz-Damgarten]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), Normalformen (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5896</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5896"/>
		<updated>2013-02-25T21:10:12Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Die Domäne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Die Domäne ==&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Zeile (oder füllt zwei Felder) in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Grundbefehle&amp;diff=5895</id>
		<title>SQL-Grundbefehle</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Grundbefehle&amp;diff=5895"/>
		<updated>2013-02-25T21:07:41Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Die Domäne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Datenbanksprache SQL dient nicht nur der Datenmanipulation (Hinzufügen, Löschen, Verändern, Lesen), sondern auch der Datenbank-Definition (dem Einrichten der Datenbank). Nachfolgend wird ein Überblick über die wichtigsten SQL-Anweisungen und der Funktion gegeben.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Erstellen von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Die angeführten Beispiele beziehen sich auf das Modell der hinterlegten Übungsdatenbank. Manipulierende SQL-Anweisungen (solche, die den Inhalt oder die Struktur der Datenbank verändern) sind in der hinterlegten Übungs-Datenbank über den eingerichteten Web-Zugang nicht ausführbar. Die Syntax der dargestellten Beispiele orientiert sich an der SQL-Implementierung der Datenbankimplementierung [http://www.mysql.com/ MySQL].&lt;br /&gt;
&lt;br /&gt;
Eine neue Tabelle wird mit der Anweisung &#039;&#039;&#039;CREATE TABLE&#039;&#039;&#039; einer bestehenden Datenbank hinzugefügt. Im nachfolgenden Beispiel wird die Tabelle mit der Bezeichnung &amp;quot;Buch&amp;quot; erstellt, welche die Spalten (Datenbankfelder) &#039;&#039;Nr&#039;&#039;, &#039;&#039;Autor&#039;&#039;, &#039;&#039;Titel&#039;&#039;, &#039;&#039;Preis&#039;&#039;, &#039;&#039;Verlag&#039;&#039;, &#039;&#039;Auslaufend&#039;&#039; und &#039;&#039;Bestand&#039;&#039; enthält.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CREATE TABLE Buch&lt;br /&gt;
(Nr SMALLINT (2) PRIMARY KEY,&lt;br /&gt;
Autor VARCHAR (20) NOT NULL,&lt;br /&gt;
Titel VARCHAR (30) NOT NULL,&lt;br /&gt;
Preis DECIMAL (3.2) NOT NULL,&lt;br /&gt;
Verlag CHAR (3) NOT NULL,&lt;br /&gt;
Auslaufend CHAR (1) NOT NULL,&lt;br /&gt;
Bestand SMALLINT (4) )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Angaben nach der Bezeichnung der Spalte (des Datenbankfeldes) definieren den Datentyp. So erzeugt der Ausdruck &amp;quot;Nr SMALLINT (2) PRIMARY KEY,&amp;quot; ein Datenbankfeld mit der Bezeichnung &amp;quot;Nr&amp;quot;, welches nur ganzzahlige Werte aufnehmen kann, die einen Speicherplatz von 4 Byte nicht überschreiten. Es handelt sich um den Wertebereich (eine Domäne) von 0 bis 65535. Die Komponente &amp;quot;PRIMARY KEY&amp;quot; weist darauf hin, dass das Feld &amp;quot;Nr&amp;quot; als Primärschlüssel Verwendung findet und einen eideutigen Wert enthalten muss.&lt;br /&gt;
&lt;br /&gt;
Die Komponente &amp;quot;NOT NULL&amp;quot; bedeutet, dass dem betreffenden Feld ein Wert zugewiesen werden muss (Muss-Feld). Fehlt diese Komponente, kann das Feld auch &amp;quot;leer&amp;quot; bleiben (Kann-Feld), wie dies im Datenbankfeld &amp;quot;Bestand&amp;quot; der Fall ist. Leer belassene Felder haben einen undefinierten Inhalt. Man kann z. B. nicht davon ausgehen, dass ein undefiniertes Feld mit numerischem Datenformat den Wert &amp;quot;0&amp;quot; aufweist.&lt;br /&gt;
&lt;br /&gt;
Vertiefende Informationen: http://dev.mysql.com/doc/refman/5.1/de/numeric-types.html&lt;br /&gt;
&lt;br /&gt;
Gängige Datenformate sind:&lt;br /&gt;
&lt;br /&gt;
* für Zahlen (z. B. SMALLINT, FLOAT, DECIMAL)&lt;br /&gt;
* für Datum und Uhrzeit (z. B. DATE, DATETIME, TIME)&lt;br /&gt;
* für Zeichenketten (z. B. CHAR, VARCHAR)&lt;br /&gt;
* für Audio- und Videoinhalte (z.B. BLOB)&lt;br /&gt;
&lt;br /&gt;
Vertiefende Informationen:  http://dev.mysql.com/doc/refman/5.1/de/data-types.html&lt;br /&gt;
&lt;br /&gt;
Moderne RDBMS und Desktop-Datenbanken bieten benutzerfreundliche Werkzeuge zur Erstellung der Tabellen an. Diese generieren die erforderliche CREATE TABLE-Anweisung aus vorliegenden Datenmodellen z.B. als ER-Diagramm, automatisch.&lt;br /&gt;
&lt;br /&gt;
==Hinzufügen eines Feldes==&lt;br /&gt;
&lt;br /&gt;
Das nachträgliche Hinzufügen einer Spalte wird mit der Anweisung &#039;&#039;&#039;ALTER TABLE&#039;&#039;&#039; bewirkt. Nachfolgende Anweisung fügt der Tabelle &#039;&#039;Buch&#039;&#039; die Spalte (das Datenbankfeld) &#039;&#039;Rabatt&#039;&#039; hinzu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ALTER TABLE Buch&lt;br /&gt;
ADD Rabatt INT (2) NOT NULL &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einfügen von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Das Eintragen von Daten in eine Tabelle geschieht mit der Anweisung &#039;&#039;&#039;INSERT INTO&#039;&#039;&#039;. Als Argumente der Anweisung müssen der Name der Tabelle mit Liste der Spaltenbezeichnungen (Feldnamen) angegeben werden. Die zugehörigen Werte (Feldinhalte) folgen dem Schlüsselwort VALUES. Nachfolgendes Beispiel bezieht sich auf die Übungsdatenbank Buchhandel und würde bei Ausführung den Bestand an Kunden um einen Datensatz ergänzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;INSERT INTO Kunde (Nr, Vorname, Nachname, Strasse, Plz)&lt;br /&gt;
VALUES (345,&#039;Maria&#039;, &#039;Huber&#039;, &#039;Columbusstrasse 1492&#039;, 2034)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Werden Werte für alle Felder in eine Tabelle übertragen, so müssen die Feldbezeichnungen nicht explizit angeführt werden, es genügt die Nennung der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Die singuläre Datenerfassung mittels INSERT INTO eignet sich nicht für Massendaten, weshalb DBMS (Datenbank Management Systeme) formularorientierte Anwendungen zur direkten Eingabe der Datensätze anbieten. Software für betriebliche Anwendungen nutzen überdies Datenbankschnittstellen, die den automatisierten Import von Daten, die z. B. aus Tabellenkalkulations-Anwendungen stammen, zulassen.&lt;br /&gt;
&lt;br /&gt;
== Löschen von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Wie auch bei der SELECT-Anweisung (siehe [[SQL-Abfragen]]) wird bei &#039;&#039;&#039;DELETE&#039;&#039;&#039; die Bedingung WHERE zur Auswahl des zu löschenden Datensatzes bestimmt. Normalerweise erfolgt dies durch die Angabe des Schlüsselfeldes des betreffenden Datensatzes. Nachfolgende Anweisung löscht den Datensatz mit der Nr &amp;quot;4&amp;quot;, wobei angenommen wird, dass das Feld &amp;quot;Nr&amp;quot; als Schlüsselfeld dient.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;DELETE FROM Kunde&lt;br /&gt;
WHERE Nr=4&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ergibt die Bedingung eine Übereinstimmung in mehreren Datensätzen, so werden alle selektierten gelöscht. Nachfolgende Anweisung löscht alle Datensätze mit dem Vornamen &amp;quot;Michael&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;DELETE FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Michael&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ändern von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Nachfolgend dargestellte Anweisung ändert im Kunden-Datensatz mit der Nr &amp;quot;4&amp;quot; den bestehenden Nachnamen auf &amp;quot;Mayer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;UPDATE Kunde&lt;br /&gt;
SET Nachname=&#039;Mayer&#039;&lt;br /&gt;
WHERE Nr=4&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es können auch mehrere Datensätze gleichzeitig mit der UPDATE-Anweisung geändert werden. Nachfolgende Anweisung ändert in jedem Datensatz, welcher den Nachnamen &amp;quot;Mayer&amp;quot; vorweist, selbigen auf &amp;quot;Neumayer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;UPDATE Kunde&lt;br /&gt;
SET Nachname=&#039;Neumayer&#039;&lt;br /&gt;
WHERE Nachname=&#039;Mayer&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nicht nur eine Spalte lässt sich in mehreren Datensätzen auf einmal ändern, sondern auch mehrere Felder in einem Datensatz. Nachfolgende Anweisung ändert im Datensatz mit der Nr &amp;quot;56&amp;quot; die PLZ auf &amp;quot;4055&amp;quot; und die Straße auf &amp;quot;Pinselweg 12&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;UPDATE Kunde&lt;br /&gt;
SET Plz=4055, Strasse=&#039;Pinselweg 12&#039;&lt;br /&gt;
WHERE Nr=&#039;56&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sonstige Anweisungen und Datenbank-Werkzeuge ==&lt;br /&gt;
&lt;br /&gt;
Die Anweisungen INSERT, DELETE und UPDATE gehören zu den wichtigsten und gehören zur Gruppe der &#039;&#039;&#039;Data Manipulation Language&#039;&#039;&#039; (&#039;&#039;&#039;DML&#039;&#039;&#039;). Daneben gibt es noch eine Vielzahl Aufgaben, Datenbanken einzurichten oder zu pflegen, die mit entsprechenden Funktionen oder Programmen unterstützt werden:&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://dev.mysql.com/doc/ MySQL.com - MySQL Documentation]&lt;br /&gt;
* [http://dev.mysql.com/doc/refman/5.1/de/installing.html MySQL.com - Installation von MySQL]&lt;br /&gt;
* [http://dev.mysql.com/doc/refman/5.1/de/optimization.html MySQL.com - Optimierung]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Grundbefehle (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Beziehungen_in_Datenbanken&amp;diff=5894</id>
		<title>Beziehungen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Beziehungen_in_Datenbanken&amp;diff=5894"/>
		<updated>2013-02-25T20:03:40Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Beziehungen zwischen Tabellen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt werden die Beziehungen zwischen Tabellen einer relationalen Datenbank erläutert. Dabei darf nicht außer Acht gelassen werden, dass sowohl der Aufbau der Tabellen, als auch die Art der Beziehung zwischen den Tabellen von den Aufgaben, die der Datenbank zu Grunde liegen, abhängen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Beziehungen zwischen Tabellen==&lt;br /&gt;
&lt;br /&gt;
Unterschiedliche Datenbank-Modelle zielen auf unterschiedliche Nutzungsaspekte ab. Datenbanken von Suchmaschinen z.B. arbeiten zwar auch mit Tabellen (Listen), die jedoch womöglich schnell Ergebnisse in kürzester Zeit, bei gleichzeitig hoher Anzahl von Anfragen liefern müssen. Redundanzen schaden in diesem Fall wenig und auch Vollständigkeit des Ergebnisses ist nicht gefragt und auch kaum nachvollziehbar.&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken müssen Nachteile bei der Verarbeitung von Massendaten in kürzester Zeit hinnehmen, erheben aber Anspruch auf Vollständigkeit der Wiedergabe abgebildeter Entitäten, sind von unterschiedlichen Anwendungen gleichzeitig nutzbar und zielen vor allem auf Reduktion von Redundanzen ab. Die Regeln zur Bildung derart redundanzarmer Tabellensysteme sind in den [[Normalformen]] festgeschrieben.&lt;br /&gt;
&lt;br /&gt;
Die von Redundanzen befreiten Tabellen einer relationalen Datenbank werden über ihre Schlüsselfelder verbunden, indem identifizierende Schlüssel (Primärschlüssel) einer Tabelle auf nicht identifizierende Schlüssel (Fremdschlüssel) anderer Tabellen verweisen. Dadurch entsteht eine Netz von Beziehungen zwischen den Tabellen einer Datenbank.&lt;br /&gt;
&lt;br /&gt;
==Funktionsweise von Schlüsseln==&lt;br /&gt;
&lt;br /&gt;
Aus gleichartigen Objekten und deren Attributen werden &#039;&#039;&#039;Objektklassen&#039;&#039;&#039; (Objekttypen, Entityklassen) gebildet. Eine &#039;&#039;&#039;Datei&#039;&#039;&#039; bildet eine Objektklasse ab; sie besteht aus einem oder mehreren Datensätzen. Jenes Feld oder jene Felder, mit denen Objekte einer Objektklasse eindeutig identifiziert werden können, werden &#039;&#039;&#039;Schlüssel&#039;&#039;&#039; (Schlüsselfeld/er) genannt. Sind Schlüssel aus mehreren Feldern zusammengesetzt, werden sie als &#039;&#039;&#039;Kombinationsschlüssel&#039;&#039;&#039; bezeichnet. &lt;br /&gt;
&lt;br /&gt;
[[Bild:Attribute_und_schluessel.gif]]&lt;br /&gt;
&lt;br /&gt;
Ein &#039;&#039;&#039;Primärschlüssel&#039;&#039;&#039; vermag genau einen und nur einen Datensatz zu identifizieren. In unserem Beispiel ist dies die pro Buch vergebene, fortlaufende Buchnummer &#039;&#039;Nr&#039;&#039;. Manchmal werden auch &#039;&#039;&#039;Sekundärschlüssel&#039;&#039;&#039; definiert, die allerdings dadurch charakterisiert sind, dass sie sich nicht zur Identifizierung genau eines Objektes (hier: Buches) eignen, sondern Datensätze mit gleichen Eigenschaften in eine Klasse zusammenfassen. Im vorliegenden Beispiel ist das Feld &#039;&#039;Verlag&#039;&#039; ein Sekundärschlüssel, der wenn er zur Anwendung kommt, alle Bücher eines bestimmten Verlages zu einer Klasse zusammenfasst.&lt;br /&gt;
&lt;br /&gt;
Welche Objektklassen im konkreten Fall zu bilden sind, welche Eigenschaften und deren Datentypen in den Feldern (Spalten) gewählt werden, hängt ausschließlich von den Erfordernissen der gestellten Aufgaben an die Datenbank ab.&lt;br /&gt;
&lt;br /&gt;
==Funktionsweise von Beziehungen==&lt;br /&gt;
&lt;br /&gt;
Damit eine relationale Datenbank ausreichend Daten zur Erfüllung gestellter Aufgaben liefern kann, ist im Regelfall die Auswertung mehrerer Tabellen notwendig. Um eine Rechnung im vorliegenden Übungsbeispiel zu erstellen, sind Daten aus den Tabellen (bzw. entsprechenden Entitäten) Kunde, Auftrag, Auftragsposition und Buch erforderlich. Da die genannten Tabellen jeweils Daten über alle Kunden, alle Aufträge, usw. enthalten, gilt es jene &#039;&#039;&#039;Menge an Daten zu selektieren&#039;&#039;&#039;, die den Erfordernissen einer Rechnung über einen bestimmten Auftrag eines bestimmten Kunden entsprechen. Die Selektion der entsprechenden Teilmenge an Daten wird durch Verbindung der relevanten Tabellen über die Schlüsselfelder, in Kombination mit Einschränkungen auf die gesuchten Entitäten, realisiert.&lt;br /&gt;
&lt;br /&gt;
Eine Beziehung zwischen den Tabellen wird durch übereinstimmende Daten in den Schlüsselfeldern (jeweils der Primärschlüssel einer Tabelle mit Fremdschlüsseln in anderen Tabellen) definiert. Im Nachfolgenden Beispiel werden die Tabellen &amp;quot;Kunde&amp;quot; und &amp;quot;Auftrag&amp;quot; über das Primär- und Fremdschlüsselfeld mit der Bezeichnung &amp;quot;Kundennummer&amp;quot; verbunden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Kunde&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Kundennummer&lt;br /&gt;
! Vorname&lt;br /&gt;
! Nachname&lt;br /&gt;
! Straße&lt;br /&gt;
! PLZ&lt;br /&gt;
|-&lt;br /&gt;
| 37&lt;br /&gt;
| Elisabeth&lt;br /&gt;
| Erlach&lt;br /&gt;
| Glimpflinger Str. 13&lt;br /&gt;
| 5020&lt;br /&gt;
|-&lt;br /&gt;
| 38&lt;br /&gt;
| Hans&lt;br /&gt;
| Hinterholzer&lt;br /&gt;
| Franziskanerweg 9&lt;br /&gt;
| 1040&lt;br /&gt;
|-&lt;br /&gt;
| 39&lt;br /&gt;
| Hans-Peter&lt;br /&gt;
| Wesp&lt;br /&gt;
| Wüstenrotstraße 23&lt;br /&gt;
| 5201&lt;br /&gt;
|-&lt;br /&gt;
| 40&lt;br /&gt;
| Konrad&lt;br /&gt;
| Gampe&lt;br /&gt;
| Berggasse 25&lt;br /&gt;
| 1010&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Auftrag&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Auftragsdatum&lt;br /&gt;
! Kundennummer&lt;br /&gt;
! Auftragsnummer&lt;br /&gt;
|-&lt;br /&gt;
| 30.03.2000&lt;br /&gt;
| 38&lt;br /&gt;
| 254&lt;br /&gt;
|-&lt;br /&gt;
| 02.05.2000&lt;br /&gt;
| 38&lt;br /&gt;
| 345&lt;br /&gt;
|-&lt;br /&gt;
| 13.01.2003&lt;br /&gt;
| 34&lt;br /&gt;
| 12743&lt;br /&gt;
|-&lt;br /&gt;
| 15.02.2003&lt;br /&gt;
| 20&lt;br /&gt;
| 3612873&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei Typen von Beziehungen, die 1:1-, 1:n- und n:m-Beziehung.&lt;br /&gt;
&lt;br /&gt;
==1:1-Beziehung==&lt;br /&gt;
&lt;br /&gt;
In einer 1:1-Beziehung ist &#039;&#039;&#039;jedem Datensatz&#039;&#039;&#039; in Tabelle &#039;&#039;A&#039;&#039; nur &#039;&#039;&#039;ein passender Datensatz&#039;&#039;&#039; in Tabelle &#039;&#039;B&#039;&#039; zugeordnet. Diese Art von Beziehung hat eine untergeordnete Bedeutung, denn den Regeln der Normalformen entsprechend müssten alle Attribute, die eine Entität beschreiben, in einer Tabelle versammelt sein.&lt;br /&gt;
&lt;br /&gt;
1:1-Beziehung werden z. B. dennoch verwenden, um eine Tabelle mit sehr vielen Feldern zu teilen, oder um einen Teil der Tabelle aus Gründen dezentraler Speicherung oder unterschiedlicher Zugriffsrechte wegen, abzutrennen.&lt;br /&gt;
&lt;br /&gt;
==1:n-Beziehung==&lt;br /&gt;
&lt;br /&gt;
Die 1:n-Beziehung ist der häufigste Beziehungstyp und damit auch der Standardfall. In der 1:n-Beziehung werden &#039;&#039;&#039;einem Datensatz&#039;&#039;&#039; in Tabelle &#039;&#039;A&#039;&#039; &#039;&#039;&#039;mehrere Datensätze&#039;&#039;&#039; in Tabelle &#039;&#039;B&#039;&#039; zugeordnet. Aber einem Datensatz in Tabelle &#039;&#039;B&#039;&#039; ist nie mehr als ein Datensatz in Tabelle &#039;&#039;A&#039;&#039; zugeordnet. Beispiel: Ein Kunde kann mehrere Aufträge erteilen, jedoch kann ein Auftrag nur von einem Kunde stammen.&lt;br /&gt;
&lt;br /&gt;
==m:n-Beziehung==&lt;br /&gt;
&lt;br /&gt;
In einer m:n-Beziehung können &#039;&#039;&#039;jedem Datensatz&#039;&#039;&#039; in Tabelle &#039;&#039;A&#039;&#039; &#039;&#039;&#039;mehrere Datensätze&#039;&#039;&#039; in Tabelle &#039;&#039;B&#039;&#039; zugeordnet sein &#039;&#039;&#039;und umgekehrt&#039;&#039;&#039;. Dieses Phänomen stammt aus der Natur der Sache.&lt;br /&gt;
&lt;br /&gt;
Einer konstruierten Vorstellung entsprechend, ist das Verhältnis zwischen Aufträgen und Büchern eine n:m Beziehung. Viele (n) Aufträge enthalten ebenfalls viele (m) Bücher. Eine direkte Zuordnung zwischen Aufträgen und Büchern ist formal nur möglich, wenn die Entität &amp;quot;Auftragspositionen&amp;quot; dazwischen installiert wird. Die Beziehungslogik lautet dann:&lt;br /&gt;
&lt;br /&gt;
Ein Auftrag enthält (hoffentlich) viele (n) Bücher (1:n)&lt;br /&gt;
Jedes Buch ist (hoffentlich) in vielen (n) Aufträgen enthalten (1:n)&lt;br /&gt;
&lt;br /&gt;
Die Entitäten (m) Aufträge und (n) Bücher werden über die zusätzlich eingeführte Entität &amp;quot;Auftragspositionen&amp;quot; mittels zwei 1:n-Beziehungen verbunden. Derart installierte Tabellen (geschaffene Entitäten) haben ein unverkennbares Merkmal: ihr Primärschlüssel besteht aus zwei geerbten Fremdschlüsseln aus den jeweils umgebenden Tabellen.&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Darstellung zeigt die Struktur der Tabellen: Auftrag, Auftragsposition und Buch sowie deren 1:n-Beziehungen, dargestellt mittels einfach (1) bzw. doppelt (n) gerichteten Kanten.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell_4.gif]]&lt;br /&gt;
&lt;br /&gt;
Diese Maßnahme führt alle Beziehungen zwischen Tabellen in relationalen Datenbanken auf 1:n-Beziehungen zurück.&lt;br /&gt;
&lt;br /&gt;
==Grafische Darstellung von Beziehungen==&lt;br /&gt;
&lt;br /&gt;
Den vorliegenden Ausführungen liegt eine Beispieldatenbank zugrunde, die einerseits als Modell für Beispiele zu den behandelten Themen dient, andererseits als interaktive Trainingsdatenbank dort eingesetzt wird, wo SQL-Anweisungen nicht nur erklärt, sondern auch zur praktischen Übung angeboten werden.&lt;br /&gt;
&lt;br /&gt;
Bei der nachfolgenden Darstellung handelt es sich um eine frei erfundene, vereinfachte Form, die zum Ziel hat, Beziehungen zwischen Tabellen in allgemein verständlicher Form zu visualisieren. Die Namen der Tabellen sind durch Fettschrift hervorgehoben, die Attribute (Felder) der Tabellen sind eingerückt unter der Bezeichnung der Tabelle angeführt. Primärschlüsselfelder sind unterstrichen. Die einfache Pfeilspitze an den Kanten zwischen den Tabellen deuten auf die &amp;quot;1&amp;quot; von &amp;quot;1:n&amp;quot;-Beziehungen hin, die doppelten Pfeilspitzen auf das &amp;quot;n&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Das Zustandekommen der dargestellten Tabellen und ihrer Beziehungen ist Gegenstand des Datenbank-Entwurfsprozesses, der an dieser Stelle nicht zum Gegenstand gemacht wird. Wie diesem Beispiel zu entnehmen ist, werden alle Tabellen nach erfolgtem Entwurfsprozess mit 1:n-Beziehungen verbunden.&lt;br /&gt;
&lt;br /&gt;
Das Arbeiten, insbesondere das Formulieren von Datenbank-Abfragen an eine konkrete Datenbank erfordert die genaue Kenntnis des Aufbaues aller Tabellen und deren Beziehungen untereinander.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Datenmodell_beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Beziehungen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5893</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5893"/>
		<updated>2013-02-25T20:00:41Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Die Domäne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Die Domäne ==&lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Zeile (oder füllt zwei Felder) in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5892</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5892"/>
		<updated>2013-02-25T19:59:35Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Die Domäne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Die Domäne ==&lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten (oder füllt zwei Felder) in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5891</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5891"/>
		<updated>2013-02-25T19:58:28Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Merkmale oder Attribute: Die Spalten der Tabelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Die Domäne ==&lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5890</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5890"/>
		<updated>2013-02-25T19:57:45Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Merkmale oder Attribute: Die Spalten der Tabelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Merkmale oder Attribute: Die Spalten der Tabelle ==&lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5889</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5889"/>
		<updated>2013-02-25T19:57:10Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Das Wesen von Tabellen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über gleichartige Objekte (Entität), wie im vorliegenden Datenbankbeispiel über Kunden, Bücher, Aufträge und Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Regeln, die auf schnelle, präzise Suchprozesse oder die einführend erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind demnach in &#039;&#039;&#039;Spalten&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen&#039;&#039;&#039; organisiert. Eine Zeile einer Tabelle entspricht einem Datensatz, der seinerseits ein verkürztes Abbild eines Objektes aus einer Menge gleichartiger Objekte (Objektklasse) repräsentiert. Eine Spalte enthält die Ausprägungen eines Merkmals aller in der Tabelle enthaltenen Objekte. Aus diesem Grunde sind die Inhalte einer Spalte vom gleichen Datentyp.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Merkmale oder Attribute: Die Spalten der Tabelle ==&lt;br /&gt;
&lt;br /&gt;
Die Spalte einer Tabelle enthält die &#039;&#039;&#039;Ausprägungen eines Merkmals&#039;&#039;&#039; (z.B. alle Preise) aller in der Tabelle abgebildeten Entitäten (z.B. aller Bücher). Darin liegt auch die Begründung, dass die Merkmalsausprägungen (Preise) vom gleichen Datentyp sind. &lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5888</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5888"/>
		<updated>2013-02-25T19:42:26Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Operationen auf Tabellen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über ein bestimmtes Objekt (Entität), wie im vorliegenden Beispiel über Kunden, Bücher oder deren Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Aspekten, die auf schnelle, gezielte Suchprozesse oder die erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind in &#039;&#039;&#039;Spalten (Feldern)&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen (Datensätzen)&#039;&#039;&#039; organisiert. Jedes &#039;&#039;&#039;Feld&#039;&#039;&#039; in der Tabelle &#039;&#039;Buch&#039;&#039; enthält &#039;&#039;&#039; den selben Informationstyp&#039;&#039;&#039; für jedes Buch, wie z. B. den &#039;&#039;Buchpreis&#039;&#039;. Jeder &#039;&#039;&#039;Datensatz&#039;&#039;&#039; in der Tabelle Buch enthält &#039;&#039;&#039;alle benötigten Informationen&#039;&#039;&#039; zu einem Buch, wie z. B. &#039;&#039;Buchnummer&#039;&#039;, &#039;&#039;Verlagskurzbezeichnung&#039;&#039;, &#039;&#039;Preis&#039;&#039;...&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Merkmale oder Attribute: Die Spalten der Tabelle ==&lt;br /&gt;
&lt;br /&gt;
Die Spalte einer Tabelle enthält die &#039;&#039;&#039;Ausprägungen eines Merkmals&#039;&#039;&#039; (z.B. alle Preise) aller in der Tabelle abgebildeten Entitäten (z.B. aller Bücher). Darin liegt auch die Begründung, dass die Merkmalsausprägungen (Preise) vom gleichen Datentyp sind. &lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Datensätze bzw. Teile (Felder) davon &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Datensätze oder Teile (Felder) davon &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Datensätze &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation &#039;&#039;&#039;Suchen&#039;&#039;&#039; begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5887</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5887"/>
		<updated>2013-02-25T19:38:46Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Geforderte Eigenschaften einer Tabelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über ein bestimmtes Objekt (Entität), wie im vorliegenden Beispiel über Kunden, Bücher oder deren Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Aspekten, die auf schnelle, gezielte Suchprozesse oder die erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind in &#039;&#039;&#039;Spalten (Feldern)&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen (Datensätzen)&#039;&#039;&#039; organisiert. Jedes &#039;&#039;&#039;Feld&#039;&#039;&#039; in der Tabelle &#039;&#039;Buch&#039;&#039; enthält &#039;&#039;&#039; den selben Informationstyp&#039;&#039;&#039; für jedes Buch, wie z. B. den &#039;&#039;Buchpreis&#039;&#039;. Jeder &#039;&#039;&#039;Datensatz&#039;&#039;&#039; in der Tabelle Buch enthält &#039;&#039;&#039;alle benötigten Informationen&#039;&#039;&#039; zu einem Buch, wie z. B. &#039;&#039;Buchnummer&#039;&#039;, &#039;&#039;Verlagskurzbezeichnung&#039;&#039;, &#039;&#039;Preis&#039;&#039;...&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Merkmale oder Attribute: Die Spalten der Tabelle ==&lt;br /&gt;
&lt;br /&gt;
Die Spalte einer Tabelle enthält die &#039;&#039;&#039;Ausprägungen eines Merkmals&#039;&#039;&#039; (z.B. alle Preise) aller in der Tabelle abgebildeten Entitäten (z.B. aller Bücher). Darin liegt auch die Begründung, dass die Merkmalsausprägungen (Preise) vom gleichen Datentyp sind. &lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. Das bedeutet, dass keines der Attribute ohne Sinnverlust in weitere Teile zerlegbar sein darf.&lt;br /&gt;
* Die enthaltenen Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt festgelegt.&lt;br /&gt;
* In jeder Tabelle existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) können. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Einen oder mehrere Datensätze &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation Suchen begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5886</id>
		<title>Tabellen in Datenbanken</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Tabellen_in_Datenbanken&amp;diff=5886"/>
		<updated>2013-02-25T19:35:21Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Geforderte Eigenschaften einer Tabelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|In diesem Lernschritt wird anhand eines Beispiels aus dem Datenbank-Lehrmodell &amp;quot;Buchhandel&amp;quot; auf die Bedeutung von Tabellen für die Modellierung von (relationalen) Datenbanken eingegangen.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Das Wesen von Tabellen==&lt;br /&gt;
Eine Tabelle ist eine strukturierte Sammlung von Daten über ein bestimmtes Objekt (Entität), wie im vorliegenden Beispiel über Kunden, Bücher oder deren Verlage. Die Anordnung der Daten in Tabellen folgt nicht grammatikalischen Regeln, wie dies einer losen Textform entspräche, sondern formalen Aspekten, die auf schnelle, gezielte Suchprozesse oder die erwähnte Freiheit von Redundanzen abzielen.&lt;br /&gt;
&lt;br /&gt;
Daten in Tabellen sind in &#039;&#039;&#039;Spalten (Feldern)&#039;&#039;&#039; und &#039;&#039;&#039;Zeilen (Datensätzen)&#039;&#039;&#039; organisiert. Jedes &#039;&#039;&#039;Feld&#039;&#039;&#039; in der Tabelle &#039;&#039;Buch&#039;&#039; enthält &#039;&#039;&#039; den selben Informationstyp&#039;&#039;&#039; für jedes Buch, wie z. B. den &#039;&#039;Buchpreis&#039;&#039;. Jeder &#039;&#039;&#039;Datensatz&#039;&#039;&#039; in der Tabelle Buch enthält &#039;&#039;&#039;alle benötigten Informationen&#039;&#039;&#039; zu einem Buch, wie z. B. &#039;&#039;Buchnummer&#039;&#039;, &#039;&#039;Verlagskurzbezeichnung&#039;&#039;, &#039;&#039;Preis&#039;&#039;...&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus der Tabelle &#039;&#039;Buch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Buchnummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Buchtitel&lt;br /&gt;
! Buchpreis&lt;br /&gt;
! Verlagskürzel&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Hronicek u.a.&lt;br /&gt;
| Elektrotechnik-Fachkunde&lt;br /&gt;
| 30,86&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Arge&lt;br /&gt;
| Metalltechnik-Grundband&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Arge&lt;br /&gt;
| Fachkunde für Tischler 2&lt;br /&gt;
| 27,07&lt;br /&gt;
| oev&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| Gitarrenschule Band 2&lt;br /&gt;
| 9,00&lt;br /&gt;
| hoe&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Merkmale oder Attribute: Die Spalten der Tabelle ==&lt;br /&gt;
&lt;br /&gt;
Die Spalte einer Tabelle enthält die &#039;&#039;&#039;Ausprägungen eines Merkmals&#039;&#039;&#039; (z.B. alle Preise) aller in der Tabelle abgebildeten Entitäten (z.B. aller Bücher). Darin liegt auch die Begründung, dass die Merkmalsausprägungen (Preise) vom gleichen Datentyp sind. &lt;br /&gt;
&lt;br /&gt;
Die Menge aller möglichen (= zugelassenen) Ausprägungen eines Merkmals (z.B. Postleitzahlen Österreichs) bilden die &#039;&#039;&#039;Domäne&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Elemente von Domänen müssen atomar sein, d. h. sie lassen sich nicht weiter in Dateneinheiten zerlegen. Die Personenbezeichnung: &amp;quot;Josef Maier&amp;quot; ist nicht atomar, sondern in den Vornamen &amp;quot;Josef&amp;quot; und Nachnamen &amp;quot;Maier&amp;quot; zerlegbar. Die Bezeichnung einer Person belegt somit zwei Spalten in der Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Geforderte Eigenschaften einer Tabelle ==&lt;br /&gt;
&lt;br /&gt;
* Eine Tabelle muss eindeutig sein. Das bedeutet, dass zu keinem Zeitpunkt zwei idente Datensätze in der Tabelle existieren dürfen.&lt;br /&gt;
* Eine Tabelle muss atomare Attribute aufweisen. &lt;br /&gt;
* Die Datensätze sind zu jedem Zeitpunkt als unsortiert anzusehen.&lt;br /&gt;
* Die Attributreihenfolge ist zu keinem Zeitpunkt fest definiert.&lt;br /&gt;
* In Tabellen existieren Attribute (singulär oder in Kombination), welche für den gesamten Datensatz als eindeutiges Identifikationsmerkmal (Schlüsselattribut) dienen. Häufig sind dies (fortlaufende) Nummern (Buchnummer, Kundennummer, Matrikelnummer, usw.).&lt;br /&gt;
&lt;br /&gt;
== Operationen auf Tabellen ==&lt;br /&gt;
&lt;br /&gt;
* Einen oder mehrere Datensätze &#039;&#039;&#039;suchen&#039;&#039;&#039;.&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;hinzufügen&#039;&#039;&#039;.&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;ändern&#039;&#039;&#039; (meist sind nur einzelne Attribute betroffen).&lt;br /&gt;
* Einen Datensatz &#039;&#039;&#039;löschen&#039;&#039;&#039;.&lt;br /&gt;
* Attribute einer Tabelle hinzufügen oder löschen.&lt;br /&gt;
* Neue Tabellen einer Datenbank hinzufügen.&lt;br /&gt;
* Tabellen aus einer Datenbank löschen.&lt;br /&gt;
&lt;br /&gt;
Die im Rahmen der vorliegenden Dokumentation eingebetteten Operationen auf die real existierende Übungsdatenbank [http://sql.idv.edu] sind auf die Operation Suchen begrenzt.&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Tabellen in Datenbanken (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Pixelgrafik&amp;diff=5885</id>
		<title>Pixelgrafik</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Pixelgrafik&amp;diff=5885"/>
		<updated>2013-02-25T15:51:06Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Multimediaformate|Multimediaformate&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Pixel- oder Rastergrafik entsteht durch Abtasten bzw. Ablichten der realen Welt. Dafür wurden populäre Geräte wie digitale Fotoapparate, Videokameras und Scanner geschaffen, die entsprechende Pendants auch in professionellen Anwendungsgebieten haben.&lt;br /&gt;
&lt;br /&gt;
Pixelgrafiken basieren von Beginn an auf einer gewählten oder durch die &amp;quot;Ablichtungstechnik&amp;quot; vorgegebenen Auflösung (Rasterung). Der Speicherbedarf von Pixelgrafiken ist um ein Vielfaches höher als bei der [[Vektorgrafik]], deshalb spielen die Verfahren der Datenkompression bei Pixelgrafiken eine besonders große Rolle. Ohne moderne Verfahren der Datenkompression (z. B. JPEG oder H.264) wäre das Internet nicht  multimedial.}}&lt;br /&gt;
&lt;br /&gt;
Ein Pixel oder Bildpunkt ist die kleinste Einheit der digitalen Rastergrafik. Der Begriff &amp;quot;Pixel&amp;quot; ist ein Akronym und setzt sich aus den englischen Begriffen &amp;quot;picture&amp;quot; und &amp;quot;element&amp;quot; zusammen. Jedes Pixel stellt den Farbwert innerhalb einer Rastergrafik dar.&lt;br /&gt;
&lt;br /&gt;
Die Bearbeitungsprozesse in pixelorientierter Grafiksoftware beziehen sich auf den Bildpunkt als Elemente der Gesamtdarstellung. Jedem Pixel werden dazu mindestens die Werte &amp;quot;Lage&amp;quot; und &amp;quot;Farb- bzw. Helligkeitswert&amp;quot; zugewiesen.&lt;br /&gt;
&lt;br /&gt;
Zur Bearbeitung von Fotos oder Grafiken steht eine Palette von Zeichenwerkzeugen zur Verfügung. Nachstehend sind die Funktionen einer typischen Werkzeugpalette der Bearbeitungssoftware &amp;quot;Photoshop&amp;quot; dargestellt:&lt;br /&gt;
&lt;br /&gt;
* Zeichenstift&lt;br /&gt;
* Pinsel&lt;br /&gt;
* Stempel&lt;br /&gt;
* Wischfinger&lt;br /&gt;
* Airbrush&lt;br /&gt;
* Radiergummi&lt;br /&gt;
* Pipette&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kopf_unbearbeitet.jpg]]   [[Datei:Kopf_nachbearbeitung.jpg]]&lt;br /&gt;
&lt;br /&gt;
Der Vergleich zwischen Ausgangsmaterial (links) und bearbeitetem Foto (rechts) zeigt das Ergebnis der Nachbearbeitungsschritte:&lt;br /&gt;
&lt;br /&gt;
* Textergänzung (roter Text im unteren Bereich des Fotos)&lt;br /&gt;
* Freihandzeichnung (blauer Pinselstrich)&lt;br /&gt;
* Anwendung eines &amp;quot;Verzerrungsfilters&amp;quot; auf einem Teilbereich des Ausgangsproduktes.&lt;br /&gt;
&lt;br /&gt;
Besonderes Augenmerk wird den &amp;quot;Filtern&amp;quot; geschenkt, mit deren Hilfe überraschende Effekte erzielt werden können:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kopf_collage.jpg]] [[Datei:Kopf_differenz.jpg‎ ]] [[Datei:Kopf_kantenbetonung.jpg‎]]&lt;br /&gt;
&lt;br /&gt;
Anwendungsmöglichkeiten für diese Art von Bildbearbeitung ergeben sich insbesondere im künstlerischen Bereich sowie in der Nachbearbeitung von Fotos.&lt;br /&gt;
&lt;br /&gt;
Pixelorientierte Grafiksoftware steht - wie viele weitere Anwendungssoftware auch - frei über den Webbrowser nutzbar zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
Probieren Sie [http://www.picnik.com/ http://www.picnik.com/]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (21.9.2009), Multimediaformate#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Pixelgrafik&amp;diff=5884</id>
		<title>Pixelgrafik</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Pixelgrafik&amp;diff=5884"/>
		<updated>2013-02-25T15:45:23Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Multimediaformate|Multimediaformate&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Pixel- oder Rastergrafik entsteht durch Abtasten bzw. Ablichten der realen Welt. Dafür wurden populäre Geräte wie digitale Fotoapparate, Videokameras und Scanner geschaffen, die entsprechende Pendants auch in professionellen Anwendungsgebieten haben.&lt;br /&gt;
&lt;br /&gt;
Pixelgrafiken basieren von Beginn an auf einer gewählten oder durch die &amp;quot;Ablichtungstechnik&amp;quot; vorgegebenen Auflösung (Rasterung). Der Speicherbedarf von Pixelgrafiken ist um ein Vielfaches höher als bei der [[Vektorgrafik]], deshalb spielen die Verfahren der Datenkompression bei Pixelgrafiken eine besonders große Rolle. Ohne moderne Verfahren der Datenkompression (z. B. JPEG oder H.264) wäre das Internet nicht  multimedial.}}&lt;br /&gt;
&lt;br /&gt;
Ein Pixel oder Bildpunkt ist die kleinste Einheit der digitalen Rastergrafik. Der Begriff &amp;quot;Pixel&amp;quot; ist ein Akronym und setzt sich aus den englischen Begriffen &amp;quot;picture&amp;quot; und &amp;quot;element&amp;quot; zusammen.&lt;br /&gt;
&lt;br /&gt;
Die Bearbeitungsprozesse in pixelorientierter Grafiksoftware beziehen sich auf den Bildpunkt als Elemente der Gesamtdarstellung. Jedem Pixel werden dazu mindestens die Werte &amp;quot;Lage&amp;quot; und &amp;quot;Farb- bzw. Helligkeitswert&amp;quot; zugewiesen.&lt;br /&gt;
&lt;br /&gt;
Zur Bearbeitung von Fotos oder Grafiken steht eine Palette von Zeichenwerkzeugen zur Verfügung. Nachstehend sind die Funktionen einer typischen Werkzeugpalette der Bearbeitungssoftware &amp;quot;Photoshop&amp;quot; dargestellt:&lt;br /&gt;
&lt;br /&gt;
* Zeichenstift&lt;br /&gt;
* Pinsel&lt;br /&gt;
* Stempel&lt;br /&gt;
* Wischfinger&lt;br /&gt;
* Airbrush&lt;br /&gt;
* Radiergummi&lt;br /&gt;
* Pipette&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kopf_unbearbeitet.jpg]]   [[Datei:Kopf_nachbearbeitung.jpg]]&lt;br /&gt;
&lt;br /&gt;
Der Vergleich zwischen Ausgangsmaterial (links) und bearbeitetem Foto (rechts) zeigt das Ergebnis der Nachbearbeitungsschritte:&lt;br /&gt;
&lt;br /&gt;
* Textergänzung (roter Text im unteren Bereich des Fotos)&lt;br /&gt;
* Freihandzeichnung (blauer Pinselstrich)&lt;br /&gt;
* Anwendung eines &amp;quot;Verzerrungsfilters&amp;quot; auf einem Teilbereich des Ausgangsproduktes.&lt;br /&gt;
&lt;br /&gt;
Besonderes Augenmerk wird den &amp;quot;Filtern&amp;quot; geschenkt, mit deren Hilfe überraschende Effekte erzielt werden können:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kopf_collage.jpg]] [[Datei:Kopf_differenz.jpg‎ ]] [[Datei:Kopf_kantenbetonung.jpg‎]]&lt;br /&gt;
&lt;br /&gt;
Anwendungsmöglichkeiten für diese Art von Bildbearbeitung ergeben sich insbesondere im künstlerischen Bereich sowie in der Nachbearbeitung von Fotos.&lt;br /&gt;
&lt;br /&gt;
Pixelorientierte Grafiksoftware steht - wie viele weitere Anwendungssoftware auch - frei über den Webbrowser nutzbar zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
Probieren Sie [http://www.picnik.com/ http://www.picnik.com/]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (21.9.2009), Multimediaformate#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL&amp;diff=5883</id>
		<title>SQL</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL&amp;diff=5883"/>
		<updated>2013-02-25T14:54:16Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Analysieren|Analysieren&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Bei moderneren Implementierungen von Datenbanken wird zwischen den Funktionen Datenbank-Client und Datenbank-Server unterschieden. Es wurden auch verteilte Datenbankkonzepte bzw. Schnittstellen zwischen Datenbanken unterschiedlicher Hersteller entwickelt. SQL-Anweisungen bzw. Schnittstellen zu SQL-Datenbanken finden nicht nur bei Datenbanksoftwarepaketen, sondern auch bei sonstigen Werkzeugen (zB bei Tabellenkalkulationsprogrammen) Berücksichtigung. Die Datenbanksprache SQL ist Gegenstand dieses Kapitels.}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
* [[SQL-Einführung]]&lt;br /&gt;
&lt;br /&gt;
* [[SQL-Grundbefehle]]&lt;br /&gt;
&lt;br /&gt;
* [[SQL-Abfragen]]&lt;br /&gt;
&lt;br /&gt;
* [[SQL-Beispielvariation]]&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5882</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5882"/>
		<updated>2013-02-25T14:51:29Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Zitiervorschlag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Verdichtung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung der Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der Treffer verringert sich, je höher die Aggregationsstufe ist. Die ermittelten Werde dagegen steigen.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5881</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5881"/>
		<updated>2013-02-25T14:50:27Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Kumulieren&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens gut verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer. Die Lerneinheit [[SQL-Beispielvariation]] beschäftigt sich mit den unterschiedlichen Aggregationsstufen.&lt;br /&gt;
&lt;br /&gt;
==Bilden von Teilmengen mit aggregierten Werten==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, auf welche die Einschränkung &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5880</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5880"/>
		<updated>2013-02-25T14:48:11Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Bilden von Teilmengen mit aggregierten Werten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Kumulieren&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens gut verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Bilden von Teilmengen mit aggregierten Werten==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, auf welche die Einschränkung &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5879</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5879"/>
		<updated>2013-02-25T14:44:15Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Umsätze je Auftrag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Verdichtung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung der Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der Treffer verringert sich, je höher die Aggregationsstufe ist. Die ermittelten Werde dagegen steigen.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5878</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5878"/>
		<updated>2013-02-25T14:42:18Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Umsätze je Auftrag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Verdichtung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung der Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der Treffer verringert sich, je höher die Aggregationsstufe ist. Die ermittelten Werde dagegen steigen.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, Auftrag.Nr, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, Auftrag.Nr, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5877</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5877"/>
		<updated>2013-02-25T14:41:01Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Umsätze je Auftrag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Verdichtung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung der Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der Treffer verringert sich, je höher die Aggregationsstufe ist. Die ermittelten Werde dagegen steigen.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, Auftrag.Nr, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, Auftrag.Nr, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5876</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5876"/>
		<updated>2013-02-25T14:38:52Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Unterschiedliche Aggregationsstufen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Verdichtung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung der Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der Treffer verringert sich, je höher die Aggregationsstufe ist. Die ermittelten Werde dagegen steigen.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Auftragsnummer und Umsatz, sortiert nach Kundennummer und Auftrag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5875</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5875"/>
		<updated>2013-02-25T14:36:42Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Aggregierung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung des Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Zahl der Treffer verringert sich, je höher die Aggregationsstufe.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Auftragsnummer und Umsatz, sortiert nach Kundennummer und Auftrag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5874</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5874"/>
		<updated>2013-02-25T14:34:27Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der vertiefenden Erläuterung der Aggregation mittels GROUP BY.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Aggregierung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung des Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Zahl der Treffer verringert sich, je höher die Aggregationsstufe.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Auftragsnummer und Umsatz, sortiert nach Kundennummer und Auftrag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5873</id>
		<title>SQL-Beispielvariation</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Beispielvariation&amp;diff=5873"/>
		<updated>2013-02-25T14:33:23Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Zitiervorschlag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Beispielvariation&amp;quot; dient der aufbauenden Erläuterung der Aggregation mittels GROUP BY Klausel. Die Anwendungsbeispiele sind als aktive Abfragen auf der Trainingsdatenbank SQL:IDV:EDU installiert.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Unterschiedliche Aggregationsstufen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachfolgende Beispiele liefern Ergebnisse mit &#039;&#039;&#039;unterschiedlichen Verdichtungsstufen (Aggregationsstufen) der Kennzahl Umsatz&#039;&#039;&#039;, beginnend mit der Auflistung der Umsätze je Auftrag, fortgesetzt mit den Umsätzen je Kunde und abschließend mit den Umsätzen je Region.&lt;br /&gt;
&lt;br /&gt;
Aus der Logik der Aggregierung ist abzuleiten, dass den Ergebnissen unterschiedliche Merkmale (Felder) beizufügen sind. In der Regel macht es keinen Sinn, Merkmale einer niedrigeren Aggregationsstufe als für die Verdichtung gewählt, in die Merkmalsliste aufzunehmen. So liefert z. B. das Merkmal &amp;quot;Auftragsnummer&amp;quot; in der Ermittlung des Umsätze je Kunde wenig Information, da Kundenumsätze in der Regel aus der Summe mehrerer Aufträge gebildet werden.&lt;br /&gt;
&lt;br /&gt;
Die Zahl der Treffer verringert sich, je höher die Aggregationsstufe.&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Auftrag==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Auftragsnummer und Umsatz, sortiert nach Kundennummer und Auftrag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr AS &#039;Kundennr.&#039;, Kunde.Nachname, Auftrag.Nr AS &#039;Auftragsnr.&#039;, SUM(Auftragspos.Menge*Buch.Preis) AS &#039;Umsatz&#039;&lt;br /&gt;
FROM Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Auftrag.Nr, Kunde.Nr, Kunde.Nachname&lt;br /&gt;
ORDER BY 2,3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Kunde==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nr&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Eingrenzung der Umsätze je Kunde auf Werte &amp;gt;= 100.000==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Kundennummer, Nachname, Ort und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY 4 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Umsätze je Region==&lt;br /&gt;
&lt;br /&gt;
Erwünscht ist eine Ergebnisliste mit den Merkmalen: Region und Umsatz, absteigend sortiert nach dem Umsatz, welcher auf zwei Nachkommastellen gerundet ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Regionsumsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), SQL-Abfragen#Überschrift (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=Datenbank-Grundlagen&amp;diff=5872</id>
		<title>Datenbank-Grundlagen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=Datenbank-Grundlagen&amp;diff=5872"/>
		<updated>2013-02-25T14:23:37Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Was sind und wozu dienen Datenbanken? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;Datenbanken|Datenbanken&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Eine wesentliche Funktion eines Computersystems besteht darin, Daten, Texte, Bilder, Sprache, Sounds (oder auch Kombinationen mehrerer Informationsarten) zu speichern, so dass deren bedarfsgerechtes, insbesondere rasches und einfaches Wiederauffinden und Nutzen ermöglicht wird.&lt;br /&gt;
&lt;br /&gt;
Das Kapitel der Datenbanken behandelt insbesondere, wie große Datenmengen dauerhaft und zuverlässig gespeichert und bei Bedarf abgerufen werden können. Dazu ist es erforderlich, die für einen oder mehrere Benutzer relevanten Ausschnitte aus der Realität einzugrenzen, und Letztere in konventionellen Dateisystemen oder in Datenbanken abzubilden. Grundlegende Fragen der Datenorganisation und der Planung von Datenbanksystemen sowie verbreitete Werkzeuge zur Nutzung von Datenbanken (insbesondere SQL) sind daher Inhalte des an dieser Stelle eingeleiteten Kapitels.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Was sind und wozu dienen Datenbanken? ==&lt;br /&gt;
&lt;br /&gt;
Datenbanken sind &#039;&#039;&#039;strukturierte Lagerstätten für Daten&#039;&#039;&#039; aller Art. Das zentrale, strukturgebende Element in Datenbanken sind &#039;&#039;&#039;Tabellen&#039;&#039;&#039;, die aus Zeilen (Sätzen) und Spalten (Feldern), bestehen. Das kleinste, atomistische Element in einer Datenbank ist die Ausprägung eines Feldes in einem konkreten Datensatz. In Tabellenkalkulationsprogrammen wird in diesem Zusammenhang von &amp;quot;Zelle&amp;quot; gesprochen und entspricht z.B. dem Nachnamen eines Kunden. Der Umfang, die Zusammensetzung und der Aufbau der Tabellen in Datenbanken bzw. deren Felder ist nicht willkürlich, sondern Regeln unterworfen. Tabellen gehören, insbesondere in &#039;&#039;&#039;Form von Listen&#039;&#039;&#039; zu millionenfach benutzten Modell organisierender, strukturierender oder auch nur darstellender Maßnahmen. Die überwiegende Mehrzahl solcher Tabellen und Listen stammt, wenn automatisiert erzeugt, aus Datenbanken. Mehr über [[Tabellen in Datenbanken]] erfahren Sie im weiterführenden Kapitel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Das Web bezieht seine&#039;&#039;&#039; sekündlich und milliardenfach, die mit Hilfe der Netze ausgelieferten und über die Browser dargestellten Inhalte vornehmlich aus Datenbanken. So gesehen ist die Facebook-Timline eines Mitgliedes eine Liste, bzw. Tabelle aus Datenbankinhalten mit den Feldern: Profilbid, Datum, Beitragsbild, Beitragstext, Anzahl der &amp;quot;Likes&amp;quot; u.a.m. welche aus einer immensen Datenbank &#039;&#039;&#039;selektiert&#039;&#039;&#039; und mit &#039;&#039;&#039;Layout-Paramtern&#039;&#039;&#039; versehen zum typischen Web-Erscheinungsbild kombiniert wird. Mit Hilfe desselben Erscheinungsbildes, man könnte es auch &#039;&#039;&#039;Forumular&#039;&#039;&#039; nennen, können die dargestellten Daten aber auch &#039;&#039;&#039;gelöscht, verändert oder ergänzt&#039;&#039;&#039; und anschließend als neuer oder veränderter Beitrag in die immense Datenbank rücktransferiert werden.&lt;br /&gt;
&lt;br /&gt;
Wie am einfachen Beispiel bereits erkennbar, enthalten Datenbanken auch &#039;&#039;&#039;unterschiedliche Datentypen&#039;&#039;&#039;, wie z.B. Texte, Datumswerte, Fotos oder auch nur die an sich winzige Information darüber, ob man etwas mag (like) oder eben nicht. Mögen, oder nicht Mögen kann im Grenzfall mehr bewirken als ein preisverdächtiges Foto und benötigt dennoch nur den Platz der allerkleinsten Speicherheinheit: dem Bit.&lt;br /&gt;
&lt;br /&gt;
Obwohl - glaubt man den Studien - sich die meisten NutzerInnen der Social Media über Wirkung und Reichweite Ihrer Postings wenig Gedanken machen, ist der Zugriff auf Einzelheiten in den Tabellen der Datenbanken mittels &#039;&#039;&#039;Zugriffsrechten&#039;&#039;&#039; lenk- und begrenzbar. Wer demnach berechtigt sein soll Daten zu lesen, löschen, verändern oder ergänzen, unterliegt eigenen Reglerwerken, von den Bedarfen unterschiedlicher Gruppierungen an Nutzern oder Rollen in Organisationen abgeleitet. &lt;br /&gt;
&lt;br /&gt;
Das soeben beispielhaft Dargelegte gilt selbstredend für ungezählte Anwendungen aus allen Bereichen in denen Computer und Netzwerke zur Lösung von Aufgaben eingesetzt werden. Im Hintergrund, weil sie sich eben auf den Oberflächen nicht immer leicht zu erkennen geben, arbeiten Datenbanken. In betrieblichen und behördlichen Informationssystemen, Freizeit- und Arbeitsumgebungen, spielerischen und ernsthaften Metiers des modernen, mobilen Lebens.&lt;br /&gt;
&lt;br /&gt;
Wer Zugriff auf die permanent wachsenden, immensen Datenbestände in Datenbanken hat, besitzt ökonomische oder politische Macht. Digitale Werkzeuge bzw. Tools (Algorithmen) zur automatisierten quantitativen und qualitativen Auswertung von Datenbeständen &#039;&#039;&#039;filtern, ordnen, berechnen und verbinden&#039;&#039;&#039; die in Tabellen scheinbar isolierten Daten zu neuen Erkenntnissen. Damit werden die Geschicke von Unternehmen gelenkt, politische Entscheidungen getroffen, die Finanzmärkte dirigiert, aber auch Leistungsbeurteilungen in Lehrveranstaltungen ermittelt. Manchmal handeln die Datenbank-auswertenden Algorithmen eigenmächtig und ohne menschliche Kontrolle. Sie kaufen und verkaufen, setzen Kurse fest. Der überwiegende Teil des Geldes, bzw. jener Werte, die Geldes wert auf Finanzmärkten gehandelt werden, lagert nicht in Scheinen und Münzen, sondern als hoffentlich gut gehüteten Zahlen in Datenbanken der Geldinstitute und Börsen, als Buchgeld bekannt. Verluste in Krisenzeiten sind demnach nicht Verluste an Banknoten, sondern &amp;quot;lediglich&amp;quot; Subtraktionen, die auf Kontodaten ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
Handeln die Daten von Menschen, sagen sie direkt oder indirekt etwas &#039;&#039;&#039;über Personen&#039;&#039;&#039; aus, so werden damit die größten Schattenseiten der Anwendung von Datenbanken angesprochen. Der Praxis effektivster und gleichzeitig schädigender Verknüpfung und Auswertung personenbezogener Daten wegen, wurde bereits Ende der 1970er Jahre in vielen Ländern der heutigen Europäischen Union ein Gesetz zum Schutz der Privatsphäre, ein Datenschutzgesezt erlassen. Mit der Verbreitung des Internets ist das Thema Datenschutz aktueller denn je und steht im diametralen Widerstreit zur bereits erwähnten wirtschaftlichen und politischen Macht derer, die insbesondere auf Daten der Nutzer des Internet und Mobilnetzen Zugriff haben.&lt;br /&gt;
&lt;br /&gt;
Den technische Hintergrund fast aller geschilderten Phänomene bilden Datenbanken in Zusammenarbeit mit Apps, Programmen, Anwendungen, Robots oder welchen Namen man den &#039;&#039;&#039;Containern von Algorithmen&#039;&#039;&#039; geben möchte.&lt;br /&gt;
&lt;br /&gt;
== Dateien ==&lt;br /&gt;
&lt;br /&gt;
Dateien bilden die Vorstufe zu den Datenbanken. Sie &amp;quot;stopfen&amp;quot; alle, für eine bestimmte Aufgabe, notwendigen Daten (Felder zu Sätzen zusammengefasst) in eine tabellarische Form. Eine Praxis, die für viele Aufgaben des Alltags ausreicht und die vorwiegende Übung der Anwendung von Tabellenkalkulationsprogrammen ist.&lt;br /&gt;
&lt;br /&gt;
=== Auch Dateien haben ihre Gesetzmäßigkeit ===&lt;br /&gt;
&lt;br /&gt;
Ein &#039;&#039;&#039;Satz&#039;&#039;&#039; (Datensatz, data record, record) bildet ein &#039;&#039;&#039;Objekt der Realität&#039;&#039;&#039; vereinfachend in einem Computersystem ab. Ein solches Objekt (Entität, entity) kann ein konkreter Gegenstand, ein Ereignis oder auch ein abstrakter Begriff sein. Es wird durch seine &#039;&#039;&#039;Attribute&#039;&#039;&#039; (Merkmale, Eigenschaften) beschrieben. Das &#039;&#039;&#039;Objekt&#039;&#039;&#039; &#039;&#039;Lehrbuch&#039;&#039; kann beispielsweise durch die Attribute &#039;&#039;Nummer&#039;&#039;, &#039;&#039;Autor&#039;&#039;, &#039;&#039;Titel&#039;&#039;, &#039;&#039;Preis&#039;&#039;, &#039;&#039;Verlag&#039;&#039;, &#039;&#039;Auslaufend&#039;&#039; und &#039;&#039;Bestand&#039;&#039; beschrieben werden. Die konkreten Inhalte der Attribute eines konkreten Lehrbuches werden &#039;&#039;&#039;Feldern&#039;&#039;&#039; (Datenfelder, fields) zugewiesen. Alle Felder eines konkreten Objektes bilden einen &#039;&#039;&#039;Datensatz&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Auszug aus einer Lehrbuch-Datei&lt;br /&gt;
|-&lt;br /&gt;
! Nummer&lt;br /&gt;
! Autor&lt;br /&gt;
! Titel&lt;br /&gt;
! Preis&lt;br /&gt;
! Verlag&lt;br /&gt;
! Auslaufend&lt;br /&gt;
! Bestand&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Oberleitner&lt;br /&gt;
| ausgewaehlte Stücke&lt;br /&gt;
| 11,69&lt;br /&gt;
| hoe&lt;br /&gt;
| n&lt;br /&gt;
| 25&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Seyr&lt;br /&gt;
| Elektrotechnik - Fachkunde 2&lt;br /&gt;
| 19,00&lt;br /&gt;
| oev&lt;br /&gt;
| n&lt;br /&gt;
| 24&lt;br /&gt;
|-&lt;br /&gt;
| 219&lt;br /&gt;
| Wanzenboeck&lt;br /&gt;
| Getting Better 2&lt;br /&gt;
| 19,70&lt;br /&gt;
| oev&lt;br /&gt;
| n&lt;br /&gt;
| 93&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Datenfelder sind mit einem Namen versehen, der sich oftmals mit der Bezeichnung des Attributes deckt und in den Spaltenüberschriften tabellarischer Darstellung auftaucht. Daten können eines unterschiedlichen Datentyps sein. Die Felder &#039;&#039;Nummer&#039;&#039; und &#039;&#039;Bestand&#039;&#039; sind z. B. vom Typ Ganzzahl, das Feld &#039;&#039;Preis&#039;&#039; vom Typ Dezimalzahl. Die Felder &#039;&#039;Autor&#039;&#039;, &#039;&#039;Titel&#039;&#039; und &#039;&#039;Verlag&#039;&#039; sind vom Typ Text und das Feld &#039;&#039;Auslaufend&#039;&#039; vom Typ Flag (mit den Ausprägungen &amp;quot;y&amp;quot; oder &amp;quot;n&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Relationale Datenbanken ==&lt;br /&gt;
&lt;br /&gt;
Datenbanken verteilen die Daten auf mehrere Tabellen, die jeweils unterschiedlich voneinander abhängen und demnach unterschiedliche Grundmodelle bilden: Hierarchien, Netze oder die auf Reduktion von Redundanzen abzielenden Relationen. Sogenannte Schlüsselfelder (keys) dienen der Verknüpfung zwischen Tabellen siehe: [[Beziehungen in Datenbanken]].&lt;br /&gt;
&lt;br /&gt;
Relational ist eine Datenbank dann, wenn die Abbilder der Entitäten derart auf Tabellen aufgeteilt sind, dass ihre Merkmale (Eigenschaften) nur in Ausnahmefällen mehrfach (redundant) gespeichert sind. Die Datenmengen können dadurch gering gehalten werden und die Daten sind vor allem integer, was so viel wie frei von Widersprüchen bedeutet. Das Anordnen der Daten in widerspruchsfreien Tabellen geschieht nach den Regeln der  [[Normalformen]]. Datenbanken nach dem relationalen Modell sind am häufigsten anzutreffen.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
=== Quellen ===&lt;br /&gt;
&lt;br /&gt;
R. Elmasri, S. B. Navathe: Grundlagen von Datenbanksystemen. Ausgabe Grundstudium. Pearson Studium 2005&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.pcwissen.eu/datenbank-grundlagen.html PCWISSEN]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (23. 2. 2013), Datenbank-Grundlagen (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5871</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5871"/>
		<updated>2013-02-25T14:17:44Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Einschränkung Datensätze aufgrund aggregierter Werte */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Kumulieren&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens gut verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Bilden von Teilmengen mit aggregierten Werten==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, welche auf die Einschränkung auf &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5870</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5870"/>
		<updated>2013-02-25T14:16:35Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Kumulieren&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens gut verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Einschränkung Datensätze aufgrund aggregierter Werte==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, welche auf die Einschränkung auf &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5869</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5869"/>
		<updated>2013-02-25T14:15:13Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Kumulieren&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens gut verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, welche auf die Einschränkung auf &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5868</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5868"/>
		<updated>2013-02-25T14:14:18Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Zusammenziehen&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens am besten verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 80.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der kumulierten Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region die im Jahr 2000 erzielt wurden, wenn dieser Wert mehr als € 80.000 je Kunde ausmacht. Das Bilden jener Teilmenge, welche auf die Einschränkung auf &amp;quot;hohe Umsätze&amp;quot;  zutrifft kann nur mit Anwendung der HAVING-Komponente erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5867</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5867"/>
		<updated>2013-02-25T14:10:46Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Zusammenziehen&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens am besten verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Aggregieren von Kennzahlen wie Umsätze, liefern wichtige Entscheidungsgrundlagen, wie im vorliegenden Fall zur Führung des Unternehmens. Die auf Regionen (Bundesländer) aggregierten Umsätze zeigen, dass der Absatzmarkt keineswegs gleich auf die Regionen verteilt ist, suggeriert aber gleichzeitig die Frage nach dem Bestand von umsatzstarken Kunden. Regionsumsätze könnten prinzipiell von vielen, kleinen Kunden stammen, oder aber auch von wenig Kunden mit entsprechend hohen Umsätzen. Die nächste und letzte Anfrage in dieser Lerneinheit richtet sich daher nach den Kunden mit hohen Umsätzen in der betrachteten Periode, wobei € 100.000 und mehr als hoch bezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
Ermittelt wird eine Liste der Kundenumsätze mit den Merkmalen: Kunde.Nummer, Kunde,Nachname, PLZ.Region und der Summe der im Jahr 2000 erzeugten Umsätze, wenn dieser Wert mehr als € 100.000 ausmacht. Das Bilden jener Teilmenge, welche aus der Einschränkung auf &amp;quot;hohe Umsätze betrifft&amp;quot; kann nur mit Anwendung der Komponente HAVING erzeugt werden. Die Einschränkung auf das Umsatzjahr 2000 bleibt davon unberührt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Region&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 80000&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5866</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5866"/>
		<updated>2013-02-25T13:50:11Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf zwei. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Zusammenziehen&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens am besten verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5865</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5865"/>
		<updated>2013-02-25T13:49:21Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf 2. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Gruppierungsfunktion &amp;quot;GROUP BY&amp;quot; wird manchmal auch als Aggregationsfunktion bezeichnet. &#039;&#039;&#039;Aggregieren&#039;&#039;&#039; bedeutet in diesem Zusammenhang auch &#039;&#039;&#039;Verdichten&#039;&#039;&#039; oder &#039;&#039;&#039;Zusammenziehen&#039;&#039;&#039;. Am Beispiel Umsatz können verschiedene Stufen des Verdichtens oder Aggregierens am besten verdeutlicht werden. Die unterste Stufe des Verdichtens von Umsätzen wäre der Auftrag. Dann folgt der Kunde und schließlich die Region. Mit der Erhöhung der Verdichtungsstufe steigen jeweils die Beträge, aber es verringert sich die Anzahl der Treffer.&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5864</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5864"/>
		<updated>2013-02-25T13:41:01Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Die Lösung erfordert etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum. Die nachfolgende Anweisung ist zwar komplexer, aber enthält keine grundsätzlich neuen Aspekte:&lt;br /&gt;
&lt;br /&gt;
* Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle,&lt;br /&gt;
* die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl&lt;br /&gt;
* und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen auf 2. Wie bei Tabellenkalkulationsprogrammen auch, können wie hier geübt, Funktionen geschachtelt angewandt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5863</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5863"/>
		<updated>2013-02-25T13:37:14Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Im ersten Anlauf werden die Umsätze der oberösterreichischen Kunden ermittelt. Etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum ist erforderlich. Die Anweisung ist komplexer, aber enthält keine grundsätzlich neuen Aspekte. Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift in der ausgegebenen Tabelle und die Funktion &amp;quot;YEAR&amp;quot; extrahiert aus einem Datumswert die Jahreszahl und die Funktion &amp;quot;ROUND&amp;quot; rundet die scheinbar unerklärlich vielen Nachkommastellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, ROUND(SUM(Auftragspos.Menge*Buch.Preis),2) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5862</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5862"/>
		<updated>2013-02-25T13:32:03Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern zuzuwenden.&lt;br /&gt;
&lt;br /&gt;
Im ersten Anlauf werden die Umsätze der oberösterreichischen Kunden ermittelt. Etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation (Preis x Mange) und die Anwendung der Summenbildung statt Minimum und Maximum ist erforderlich. Die Anweisung ist komplexer, aber enthält keine grundsätzlich neuen Aspekte. Der Ausdruck &amp;quot;AS&amp;quot; ändert lediglich die Spaltenüberschrift.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT PLZ.Region, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND YEAR(Auftrag.Datum) = &#039;2000&#039; &lt;br /&gt;
GROUP BY PLZ.Region&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT PLZ.Region, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND YEAR(Auftrag.Datum) = &#039;2000&#039;  GROUP BY PLZ.Region ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5861</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5861"/>
		<updated>2013-02-25T13:14:16Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern. Mit einem Wurf, kann und wird es noch nicht gelingen. Schritt für Schritt ist der bessere Lösungsweg:&lt;br /&gt;
&lt;br /&gt;
Im ersten Anlauf werden die Umsätze der oberösterreichischen Kunden ermittelt. Etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation und die Anwendung der Summenbildung ist erforderlich. Die Anweisung ist komplexer, aber enthält keine grundsätzlich neuen Aspekte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Plz, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND PLZ.Region = &#039;o&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Plz&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Plz, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND PLZ.Region = &#039;o&#039; GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Plz ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5860</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5860"/>
		<updated>2013-02-25T13:12:34Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern. Mit einem Wurf, kann und wird es noch nicht gelingen. Schritt für Schritt ist der bessere Lösungsweg:&lt;br /&gt;
&lt;br /&gt;
Im ersten Anlauf werden die Umsätze der oberösterreichischen Kunden ermittelt. Etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation und die Anwendung der Summenbildung ist erforderlich. Komplexer, aber nicht grundsätzlich neu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Plz, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND PLZ.Region = &#039;o&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Plz&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Plz, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz = Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr AND PLZ.Region = &#039;o&#039; GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Plz ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5859</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5859"/>
		<updated>2013-02-25T13:10:32Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Es ist an der Zeit, sich der letzten, der eingangs erwähnten Anfragen an die Übungsdatenbank zuzuwenden: Die kumulierten Umsätze aller Kunden des Jahres 2000, aufgelistet nach Bundesländern. Mit einem Wurf, kann und wird es noch nicht gelingen. Schritt für Schritt ist der bessere Lösungsweg:&lt;br /&gt;
&lt;br /&gt;
Im ersten Anlauf werden die Umsätze der oberösterreichischen Kunden ermittelt. Etwas mehr Joins (Verbindungen zwischen Tabellen) als bis jetzt, eine Multiplikation und die Anwendung der Summenbildung ist erforderlich. Komplexer, aber nicht grundsätzlich neu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Ort SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND PLZ.Region = &#039;o&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Ort&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, Kunde.Ort SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz = Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
AND PLZ.Region = &#039;o&#039;&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, Kunde.Ort&lt;br /&gt;
ORDER BY SUM(Auftragspos.Menge*Buch.Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5857</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5857"/>
		<updated>2013-02-25T12:49:10Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Auswählen und Ausgeben von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemiebücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Die vorliegende Lerneinheit soll Sie befähigen, die soeben formulierten Fragen zu beantworten.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5856</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5856"/>
		<updated>2013-02-25T12:31:53Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Auswählen und Ausgeben von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F | Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5855</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5855"/>
		<updated>2013-02-25T12:30:49Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Auswählen und Ausgeben von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F Datenbankgrundlagen]].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5854</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5854"/>
		<updated>2013-02-25T12:30:05Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Auswählen und Ausgeben von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F Datenbankgrundlagen].&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5853</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5853"/>
		<updated>2013-02-25T12:09:11Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Rechenoperationen mit SQL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F]]&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis aller geführten Bücher.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5852</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5852"/>
		<updated>2013-02-25T12:03:18Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Gruppieren von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F]]&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen mit SQL ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Maximalwert wurde in diesem Fall aus der Menge aller in der Tabelle gespeicherten Preise ermittelt und es wäre vermessen nach dem Titel oder Autor des Buches mit dem höchsten Preis zu fragen. Theoretisch besteht die Möglichkeit, dass viele, im Grenzfall alle Bücher denselben hohen Preis aufweisen. Welches Buch würde man dann als das höchstpreisigste ausweisen?&lt;br /&gt;
&lt;br /&gt;
Nicht viel anders ist das Ergebnis aus einer eingeschränkten Menge an Büchern zu interpretieren: Was ist der höchste Preis der Bücher des Verlages &#039;manz&#039;?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Verlag = &#039;manz&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch WHERE Verlag = &#039;manz&#039;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit € 93,52 liegt dieser etwas unter dem absoluten Höchstpreis.&lt;br /&gt;
&lt;br /&gt;
Führen gegenständliche Überlegungen nicht dazu, sich systematisch-vergleichende Auswertungen zu wünschen? Z.B. als Auflistung der höchsten und niedrigsten Buchpreise, gruppiert (bezogen) auf die jeweiligen Verlage? Für diesen, weitaus mächtigeren Anwendungsfall komplexer Rechenoperation steht die GROUP BY Komponente zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Verlag, MAX(Preis), MIN(Preis)&lt;br /&gt;
FROM Buch&lt;br /&gt;
GROUP BY Verlag&lt;br /&gt;
ORDER BY MAX(Preis) DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Verlag, MAX(Preis), MIN(Preis) FROM Buch GROUP BY Verlag ORDER BY MAX(Preis) DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist zu erwarten, dass komplexe Rechenoperationen nicht nur auf Maxima und Minima begrenzt sind. Eine Auswahl, weiterer, geläufiger findet sich nachfolgend:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
Mit der Gruppenfunktion generierte Spalten können mit &#039;&#039;&#039;AS&#039;&#039;&#039; benannt und dadurch auch für weitere Aktionen (z. B. ORDER BY) innerhalb derselben Abfrage verwendet werden. Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5851</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5851"/>
		<updated>2013-02-25T11:27:48Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Gruppieren von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F]]&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gruppieren von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge, was mit € 116,90 für ein Schulbuch stolz ausfällt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine Auswahl geläufiger Funktionen wäre:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;GROUP BY&#039;&#039;&#039;-Klausel bewirkt, dass die aus einer Abfrage resultierende Tabelle in &#039;&#039;&#039;Gruppen&#039;&#039;&#039; gegliedert wird. Dazu muss in der GROUP BY-Klausel angegeben werden, nach welchem Kriterium die Gruppierung erfolgen soll. Dieses Kriterium, der &#039;&#039;&#039;Gruppierungsschlüssel&#039;&#039;&#039;, ist im einfachsten Fall ein Attribut der Ausgangstabelle. Alle Zeilen mit demselben Wert des Gruppierungsschlüssels fallen in dieselbe Gruppe. Eine Gruppe ist also nichts anderes als eine Teiltabelle. Im Ergebnis wird jede Gruppe durch die Anwendung von Gruppierungsfunktionen auf eine einzelne Zeile zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Abfrage gibt das gruppierte Feld &#039;&#039;Region&#039;&#039; und die Anzahl der Orte, die &amp;quot;kirche&amp;quot; enthalten, aus der Tabelle &#039;&#039;PLZ&#039;&#039; aus und sortiert diese neue Tabelle absteigend anhand der zweiten Spalte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Region, COUNT(*)&lt;br /&gt;
FROM PLZ&lt;br /&gt;
WHERE Ort LIKE &#039;%kirche%&#039;&lt;br /&gt;
GROUP BY Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Region, COUNT(*) FROM PLZ WHERE Ort LIKE &#039;%kirche%&#039; GROUP BY Region ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Gruppenfunktion generierte Spalten können mit &#039;&#039;&#039;AS&#039;&#039;&#039; benannt und dadurch auch für weitere Aktionen (z. B. ORDER BY) innerhalb derselben Abfrage verwendet werden. Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
	<entry>
		<id>https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5850</id>
		<title>SQL-Abfragen</title>
		<link rel="alternate" type="text/html" href="https://mussswiki.idb.edu/iv1wiki/index.php?title=SQL-Abfragen&amp;diff=5850"/>
		<updated>2013-02-25T11:26:13Z</updated>

		<summary type="html">&lt;p&gt;Hans4mido: /* Gruppieren von Datensätzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&amp;lt;yambe:breadcrumb&amp;gt;SQL|SQL&amp;lt;/yambe:breadcrumb&amp;gt;--&amp;gt;&lt;br /&gt;
{{Kurzform|Die Lerneinheit &amp;quot;SQL-Abfragen&amp;quot; dient der Erläuterung unterschiedlicher Anwendungsfälle der SQL-Anweisung &amp;quot;SELECT&amp;quot;, die jeweils mit interaktiv ausführbaren Beispielen hinterlegt sind. Diese Beispiele beziehen sich auf die Trainingsdatenbank [http://sql.idv.edu].}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Die SELECT Anweisung==&lt;br /&gt;
&lt;br /&gt;
Relationale Datenbanken können mit Hilfe der &#039;&#039;&#039;SELECT&#039;&#039;&#039;-Anweisung ausgewertet werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung eines SQL-Trainingsservers, welcher als interaktive Anwendung auch unter [http://sql.idv.edu/ http://sql.idv.edu] erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank über die vorliegende Schnittstelle erlauben lediglich die Anwendung der SELECT-Anweisung. Das Ausführun von Anweisungen, welche die Struktur oder den Inhalt der Datenbank ändern könnten, werden abgewiesen.&lt;br /&gt;
&lt;br /&gt;
Den interaktiven Abfragen liegt folgendes Datenmodell zu Grunde:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Datenmodell beispieldatenbank.gif]]&lt;br /&gt;
&lt;br /&gt;
== Auswählen und Ausgeben von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Formulierung von Abfragen mittels SELECT-Anweisung ist die Anwendung von mengentheoretischen Grundkenntnissen sehr hilfreich. Grundsätzlich sind mittels SELECT alle Datensätze aller Tabellen einer Datenbank auswählbar (selektierbar). Die Kunst der richtigen Anwendung besteht aber darin, durch das Formulieren von Schnitt- und Vereinigungsmengen das richtige Ergebnis (= der gestellten Aufgabe entsprechende Menge) zu bilden. Beispiele für Anfragen an die vorliegenden Übungs-Datenbank sind:&lt;br /&gt;
&lt;br /&gt;
* Die vollständigen Adressen aller Kunden in Nieder- und Oberösterreich.&lt;br /&gt;
* Eine Liste aller Chemie-Bücher des Verlages &#039;manz&#039;.&lt;br /&gt;
* Die kumulierten Umsätze des Jahres 2000 aller Kunden, absteigend aufgelistet nach Bundesländern.&lt;br /&gt;
&lt;br /&gt;
Alle Ergebnisse einer SELECT-Anweisung werden in Form von Listen (bzw. Tabellen) erzielt. In der Praxis sind die erzielten Ergebnisse Teil einer (Computer)Anwendung, welche aus dem unermesslichen Repertoire an Anwendungen stammt und an dieser Stelle keine weitere Behandlung mehr bedarf. Siehe: [[Datenbank-Grundlagen#Was_sind_und_wozu_dienen_Datenbanken.3F]]&lt;br /&gt;
&lt;br /&gt;
Die Idee der Auswertung dieser Übungs-Datenbank ist die Weiterverarbeitung in Tabellenkalkulationsprogrammen. Zu diesem Zwecke wird am Ende jedes Ergebnisses (jeder Ausgabe) die Funktion &amp;quot;Download as CSV&amp;quot; angeboten.&lt;br /&gt;
&lt;br /&gt;
== SELECT- Die Grundform ==&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel erzeugt eine Liste aller Vornamen der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;). Die Grundform verlangt mindestens die Komponenten SELECT und FROM. Nach der Komponente SELECT wollen die Namen der Spalten (Felder) genannt werden, nach dem FROM jene Tabelle(n) aus denen die gesuchten Felder stammen. Das Einstiegsbeispiel such alle Vornamen der Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchte man mehr als ein Feld aufgelistet haben, so werden diese durch Komma getrennt nacheinander angeführt. Nachfolgendes Beispiel sucht nach den Inhalten der Felder &#039;&#039;Vorname&#039;&#039;, &#039;&#039;Nachname&#039;&#039; und &#039;&#039;Plz&#039;&#039; der Kunden (aus der Tabelle &#039;&#039;Kunde&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, Plz&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, Plz FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkenswert ist, dass alle Datensätze der Tabelle &amp;quot;Kunde&amp;quot; ausgewählt und ausgegeben werden und diese prinzipiell unsortiert sind.&lt;br /&gt;
&lt;br /&gt;
Ist die Anzahl der Felder, bzw. deren Namen unbekannt, so führt folgendes SELECT zur Auswahl aller Datensätze mit all ihren Feldern. Der gesamte Inhalt der Tabelle &amp;quot;Kunde&amp;quot; wird demnach selektiert und ausgegeben. 999 Kunden sollen gefunden und angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT *&lt;br /&gt;
FROM Kunde&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT * FROM Kunde&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sortieren der Datensätze und Ausschließen von Wiederholungen ==&lt;br /&gt;
&lt;br /&gt;
Gleiche Inhalte von Feldern in unterschiedlichen Datensätzen ist keine Seltenheit. Es würde überraschen, wenn bei 999 Kunden manche Vornamen nicht mehrfach vorkämen. Eine einfache Methode dies zu überprüfen ist, die Reihenfolge der Vornamen der Kunden alphabetisch zu sortieren. Das SELECT-FROM wird um die Komponente ORDER BY ergänzt. &amp;quot;ASC&amp;quot; steht für ascending, was aufsteigend sortiert bedeutet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das Ergebnis überprüft? Wer hätte gedacht, dass gleich zu Beginn der Liste 9 Achims angeführt werden? Sollen alle Duplikate aus der Liste entfernt werden, so kommt die Komponente DISTINCT zum Einsatz. Jeder Vorname wird nur eine einziges Mal angeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT DISTINCT Vorname&lt;br /&gt;
FROM Kunde&lt;br /&gt;
ORDER BY Vorname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT DISTINCT Vorname FROM Kunde ORDER BY Vorname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selektieren von Datensätzen - Bilden von Teil- und Vereinigungsmengen ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn dieser Lerneinheit war von mengentheoretischen Überlegungen die Rede. Die Komponente DISTINCT hat zwar zur Bildung einer Teilmenge aus der Menge aller Vornamen bereits beigetragen, aber diese Methode ist für die meisten Bedarfe nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Die WHERE-Komponente in Verbindung mit den nachfolgend angeführten Operatoren ermöglicht das Bilden von Vereinigungs- und Teilmengen unter Verwendung von Klammern, Vergleichsperatoren, Rechenoperationen und logischen Verbindungen.&lt;br /&gt;
&lt;br /&gt;
# ( )&lt;br /&gt;
# * /&lt;br /&gt;
# + -&lt;br /&gt;
# = &amp;lt;&amp;gt; &amp;gt; &amp;lt; like&lt;br /&gt;
# NOT AND OR&lt;br /&gt;
&lt;br /&gt;
Neun Kunden mit dem Vornamen Achim befinden sich in der Datenbank. Gesucht sind nun der Vorname, der Nachname und die Postleitzahl jener Kunden, deren Vornamen auf Achim lauten. Die Treffer sollten aufsteigend nach dem Nachnamen aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Vorname, Nachname, PLZ&lt;br /&gt;
FROM Kunde&lt;br /&gt;
WHERE Vorname=&#039;Achim&#039;&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Vorname, Nachname, PLZ FROM Kunde WHERE Vorname=&#039;Achim&#039; ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie wäre es nun mit der eingangs erwähnten Auflistung aller Chemiebücher, des Verlages &#039;manz&#039; ? Die Lösung soll in kleinen Schritten erfolgen. Zuerst werden die Chemiebücher gesucht. Chemiebücher enthalten im Titel den Text &amp;quot;Chemie&amp;quot;. Das &amp;quot;%-Zeichen&amp;quot; steht jeweils für einen beliebigen Text vor und nach dem gesuchten Textteil, was der Formulierung &amp;quot;Der Titel enthält den Textteil &#039;Chemie&#039;&amp;quot; entspricht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im zweiten Schritt wird den Chemiebüchern die Einschränkung auf Bücher des Verlages &#039;manz&#039; unter Nutzung des logischen Operators &amp;quot;AND&amp;quot; hinzugefügt. Die Menge aller Chemiebücher wird mit der Menge der Bücher des Verlages &#039;manz&#039; geschnitten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND Verlag = &#039;manz&#039;&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND Verlag = &#039;manz&#039; ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung gefällig? Das Ergebnis der Chemiebücher des Verlages &#039;manz&#039; zeigt gerade 6 Treffer. Als passionierter Buchhändler kennt man die Bedeutung des Verlages &#039;oev&#039; und vermutet dort auch ein umfassendes Angebot. Der Sinn der gegenständlichen Einschränkung ist jedoch, Angebote kleinerer Verlage zu finden. Es liegt daher nahe, das Angebot an Chemie-Büchern des Verlages &#039;manz&#039; um gleichnamige Angebote der Verlage &#039;ha&#039; und &#039;wpr&#039; zu erweitern. Eine, im Kern mengentheoretische Aufgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Schneiden Sie die Menge aller Chemiebücher&lt;br /&gt;
mit der Vereinigungsmenge aller Bücher der Verlage: &#039;manz&#039;, &#039;ha&#039; und &#039;wpr&#039;. &amp;lt;/pre&amp;gt; Auf SQL übersetzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Titel, Preis, Autor, Verlag&lt;br /&gt;
FROM Buch&lt;br /&gt;
WHERE Titel like &#039;%Chemie%&#039;&lt;br /&gt;
AND (Verlag = &#039;manz&#039;&lt;br /&gt;
OR Verlag = &#039;ha&#039;&lt;br /&gt;
OR Verlag = &#039;wpr&#039;)&lt;br /&gt;
ORDER BY Verlag&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Titel, Preis, Autor, Verlag FROM Buch WHERE Titel like &#039;%Chemie%&#039; AND (Verlag = &#039;manz&#039; OR Verlag = &#039;ha&#039; OR Verlag = &#039;wpr&#039;) ORDER BY Verlag&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;AND&#039;, &#039;OR&#039; mit Klammern richtig strukturiert erzeugen des Rätsels Lösung. Sollten Sie sich an dieser Stelle an die [http://stubber.math-inf.uni-greifswald.de/analysis/schimming/analysis.pdf Grundlagen der Analysis] erinnern, so liegen Sie keineswegs falsch!&lt;br /&gt;
&lt;br /&gt;
== Verbinden von Tabellen ==&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung fast aller Aufgaben aus dem Datenbank-Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch &#039;&#039;Join&#039;&#039; und wird ebenfalls in der WHERE-Komponente formuliert.&lt;br /&gt;
&lt;br /&gt;
Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus &#039;&#039;Vorname&#039;&#039; wird &#039;&#039;Kunde.Vorname&#039;&#039;, aus Preis wird Buch.Preis usw. Diese Maßnahme ist dann unerlässlich, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Das Feld &#039;&#039;Kunde.Nr&#039;&#039; muss z. B. von der &#039;&#039;Artikel.Nr&#039;&#039; und diese von der &#039;&#039;Buch.Nr&#039;&#039; unterschieden werden können.&lt;br /&gt;
&lt;br /&gt;
Die Verbindung der beteiligten Tabellen erfolgt über die Schlüsselfelder. Da im vorliegenden Beispiel ausschließlich 1:n Verbindungen zur Anwendung kommen &#039;&#039;&#039;wird immer der Primärschlüssel einer Tabelle einem Fremdschlüssel einer weiteren Tabelle gleich gesetzt&#039;&#039;&#039;. Folgen Sie den gerichteten Kanten in der [http://sql.idv.edu/skalierbar/datenmodell_3.swf Grafik], diese weisen den Weg der Verbindungen (Joins).&lt;br /&gt;
&lt;br /&gt;
Die augenfälligste Forderung nach einer Verbindung von Tabellen ergibt sich aus der Notwenigkeit vollständiger Kundenadressen. Da die Ortsnamen der 3. Normalform wegen in eine eigene Tabelle mit der Bezeichnung PLZ ausgelagert wurden, ist die Verbindung der Tabellen PLZ und Kunde unerlässlich. Nachfolgend unspektakulär scheint dann die Lösung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
ORDER BY Ort, Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz ORDER BY Ort, Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NICHT dass Sie nun denken: entweder Joins - oder Bilden von Teil- und Vereinigungsmengen. Die WHERE-Komponente verträgt beides. Sind jetzt die vollständigen Adressen der Kunden aus Nieder- und Oberösterreich gefällig?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort&lt;br /&gt;
FROM Kunde, PLZ&lt;br /&gt;
WHERE Kunde.Plz=PLZ.Plz&lt;br /&gt;
AND (PLZ.Region = &#039;o&#039;&lt;br /&gt;
OR PLZ.Region = &#039;n&#039;)&lt;br /&gt;
ORDER BY Nachname ASC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Strasse, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE Kunde.Plz=PLZ.Plz AND (PLZ.Region = &#039;o&#039; OR PLZ.Region = &#039;n&#039;) ORDER BY Nachname ASC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gruppieren von Datensätzen ==&lt;br /&gt;
&lt;br /&gt;
Die Datenbanksprache SQL kann auch &#039;&#039;&#039;Rechenoperationen auf Suchergebnisse in relationalen Datenbanken&#039;&#039;&#039; durchführen und bildet damit in gewisser Weise Konkurrenz zu Tabellenkalkulationsprogrammen. Wie in den Letztgenannten auch, werden mit Ausnahme der Grundrechnungsarten (+, -, *, /) komplexe Operationen als Funktion formuliert; mit vorangestelltem Funktionsnamen, dem die Argumente in Klammern gesetzt folgen. Der Ausdruck: MAX(Buch.Preis) liefert demnach den höchsten Preis der im SELECT definierten Menge.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT MAX(Preis)&lt;br /&gt;
FROM Buch&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT MAX(Preis) FROM Buch&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine Auswahl geläufiger Funktionen wäre:&lt;br /&gt;
&lt;br /&gt;
* COUNT&lt;br /&gt;
* SUM&lt;br /&gt;
* AVG&lt;br /&gt;
* MAX&lt;br /&gt;
* MIN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;GROUP BY&#039;&#039;&#039;-Klausel bewirkt, dass die aus einer Abfrage resultierende Tabelle in &#039;&#039;&#039;Gruppen&#039;&#039;&#039; gegliedert wird. Dazu muss in der GROUP BY-Klausel angegeben werden, nach welchem Kriterium die Gruppierung erfolgen soll. Dieses Kriterium, der &#039;&#039;&#039;Gruppierungsschlüssel&#039;&#039;&#039;, ist im einfachsten Fall ein Attribut der Ausgangstabelle. Alle Zeilen mit demselben Wert des Gruppierungsschlüssels fallen in dieselbe Gruppe. Eine Gruppe ist also nichts anderes als eine Teiltabelle. Im Ergebnis wird jede Gruppe durch die Anwendung von Gruppierungsfunktionen auf eine einzelne Zeile zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Abfrage gibt das gruppierte Feld &#039;&#039;Region&#039;&#039; und die Anzahl der Orte, die &amp;quot;kirche&amp;quot; enthalten, aus der Tabelle &#039;&#039;PLZ&#039;&#039; aus und sortiert diese neue Tabelle absteigend anhand der zweiten Spalte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Region, COUNT(*)&lt;br /&gt;
FROM PLZ&lt;br /&gt;
WHERE Ort LIKE &#039;%kirche%&#039;&lt;br /&gt;
GROUP BY Region&lt;br /&gt;
ORDER BY 2 DESC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Region, COUNT(*) FROM PLZ WHERE Ort LIKE &#039;%kirche%&#039; GROUP BY Region ORDER BY 2 DESC&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit der Gruppenfunktion generierte Spalten können mit &#039;&#039;&#039;AS&#039;&#039;&#039; benannt und dadurch auch für weitere Aktionen (z. B. ORDER BY) innerhalb derselben Abfrage verwendet werden. Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar. Sie gibt die Spalten &#039;&#039;Kunde.Nr&#039;&#039;, &#039;&#039;Kunde.Nachname&#039;&#039;, &#039;&#039;PLZ.Ort&#039;&#039; und den errechneten Umsatz aus den Tabellen &#039;&#039;PLZ&#039;&#039;, &#039;&#039;Kunde&#039;&#039;, &#039;&#039;Auftrag&#039;&#039;, &#039;&#039;Auftragspos&#039;&#039; und &#039;&#039;Buch&#039;&#039; aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Selektion (Einschränkung) auf eine Gruppierung (Aggregierung) von Datensätzen==&lt;br /&gt;
&lt;br /&gt;
Besteht der Bedarf, das Ergebnis einer Aggregatsfunktion einzuschränken, so geschieht dies nicht in der WHERE Klausel, sondern in der HAVING Klausel, welche nach dem GROUP BY zur Anwendung kommt.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Der ermittelte Kundenumsatz aus obigem Beispiel soll auf jene Kunden eingeschränkt werden, deren Umsatz den Betrag von 100000 erreicht oder übersteigt. Erwartet wird eine Liste der Kundenumsätze mit den Merkmalen: Nummer, Nachname, Ort und Summe, sortiert nach dem Nachnamen des Kunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;http://sql.idv.edu/thema/work/sql.php&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;select&amp;quot; value=&amp;quot;SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz&lt;br /&gt;
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch&lt;br /&gt;
WHERE PLZ.Plz=Kunde.Plz&lt;br /&gt;
AND Kunde.Nr=Auftrag.Kundennummer&lt;br /&gt;
AND Auftrag.Nr=Auftragspos.Auftragsnummer&lt;br /&gt;
AND Auftragspos.Buchnummer=Buch.Nr&lt;br /&gt;
GROUP BY Kunde.Nr, Kunde.Nachname, PLZ.Ort&lt;br /&gt;
HAVING SUM(Auftragspos.Menge*Buch.Preis) &amp;gt;= 100000&lt;br /&gt;
ORDER BY Kunde.Nachname&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Ausführen&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== Weiterführende Links ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sql-und-xml.de/sql-tutorial/ http://www.sql-und-xml.de/sql-tutorial/]&lt;br /&gt;
&lt;br /&gt;
== Zitiervorschlag ==&lt;br /&gt;
&#039;&#039;Mittendorfer&#039;&#039; in &#039;&#039;Pils&#039;&#039;, Informationsverarbeitung I (24. 2. 2013), SQL-Abfragen  (mussswiki.idv.edu/iv1)&lt;/div&gt;</summary>
		<author><name>Hans4mido</name></author>
	</entry>
</feed>