1. #1
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.080
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard Einführung in SQL SELECT-Abfragen

    Mal wieder eine kleine Zusammenfassung für eine Arbeit. Dieses mal geht es um SELECT-Anfragen in SQL.
    Wir hatten da im Unterricht paar Tabellen zu irgendeinem Online-Shop, deswegen nehm ich hier auch mal so was als Beispiel-Datensätze

    customer

    customer_id name firstname
    email adress zip city
    1 Müller Dieter dieter.mueller@gmail.com Müllerweg 1 1337 Müllerhausen
    2 Werner Thomas thomas.werner@gmx.de Alter Weg 5 1011 Amsterdam
    3 Maier Tom tom.maier@web.de Neuer Weg 10 1102 Amsterdam

    items

    item_id title description price stock
    1 Belina TFT Monitor 22" Riesen Monitor mit FullHD Auflösung 99,99 10
    2 Samsung Galaxy S4 Samsung Galaxy S4 schwarz, 16GB internen Speicher 499 1337
    3 Samsung Galaxy S4 Schutzfolie Schutzfolie für das Samsung Galaxy S4 0,99 104
    4 Be quiet! 600W Netzteil Be quiet! 600W PC Netzteil mit hohem Wirkungsgrad 79,99 55

    orders

    customer_id item_id
    1 2
    3 4
    3 1

    Grundwissen

    Eine einfache SELECT-Abfrage hat folgenden Aufbau:
    SELECT spaltenname
    FROM tabelle;


    SQL-Schlüsselwörter wie SELECT oder FROM scheibt man normal immer in Blockschrift. Das hat nichts damit zutun, dass SQL case-sensitive ist. Prinzipiell ist das wurst, 'select' oder 'from' wäre genau so valide. So ist es aber übersichtlicher, daher empfehle ich, die Schlüsselwörter groß zu schreiben.
    Möchte man alle Spalten und Datensätze einer Tabelle ausgeben, geht das am Beispiel der Kunden-Tabelle so:

    SELECT *
    FROM items;

    Der Stern * ist ein Quantifizer eines Regulären Ausdrucks und ist im alltäglichen Gebrauch als Jokerzeichen bekannt geworden. Hier hat er nicht die gleiche Bedeutung wie in einem Regulären Ausdruck, sondern steht wie etwa in der Suchmaske für Dateien für jedes beliebige Zeichen. Hier steht es für den Name der Spalte und man bekommt als Ausgabe also alle Datensätze in der Tabelle:

    Name:  sql-select-all.png
Hits: 406
Größe:  10,9 KB

    Möchte man nur bestimmte Spalten (zb Name und Vorname), gibt man diese im SELECT-Teil an:

    SELECT name, firstname
    FROM customer;

    Dies würde nur die zwei Spalten Name und Vorname aller Datensätze anzeigen.
    Generell sollte man SELECT * vermeiden und es keinesfalls als Universal-Lösung sehen um sich das angeben der Spalten zu sparen! Da wie gesagt alle Datensätze ausgegeben werden ist dieser Befehl für die meisten Abfragen inperformant, da man meistens eben nicht alle Spalten benötigt. Der SQL-Server wird dabei stärker belastet und es entsteht overhead zwischen Fronted und Datenbankserver.

    Bedingungen

    Sollen nur bestimmte Daten angezeigt werden (zb nur Kunden aus Amsterdam), ist das in dem Beispiel noch recht einfach von Hand trennbar. Da das bei einer größeren Datenbank mit hunderttausenden Datensätzen welche Kunden vom der ganzen Erde beinhalten natürlich nicht mehr so einfach ist, kann man die Datensätze mit Bedingungen eingrenzen. Dies geschieht mittels WHERE.

    Syntax:
    SELECT * 
    FROM customer
    WHERE {Bedingung};

    Es gibt mehrere Arten von Bedingungen. Am häufigsten verwendet man direkte Übereinstimmungen, etwa wie bei obigem Beispiel wo alle Kunden aus Amsterdam ausgegeben werden sollen:
    SELECT name, firstname 
    FROM customer
    WHERE city = 'Amsterdam';

    Natürlich können auch mehrere Bedingungen mit den logischen Operatoren verknüpft werden. Möchte man zb alle Kunden die mit Nachname Werner heißen und in Amsterdam wohnen sähe die Abfrage so aus:
    SELECT * 
    FROM customer
    WHERE city = 'Amsterdam'
    AND name = 'Werner';


    Man kann bei Strings auch Teildaten angeben. Dies braucht man häufig bei Suchfunktionen. Wenn jemand als Beispiel 'Galaxy S4' in eine Suchmaske eingibt würde bei einer Equal-Prüfung kein Artikel ausgegeben werden. Das ist natürlich nicht sehr sinnvoll, da der Kunde vermutlich das Handy oder Zubehör dafür sucht. Daher können mit LIKE Platzhalter gesetzt werden:

    SELECT *
    FROM items
    WHERE title LIKE '*Galaxy S4*';

    Anmerkung: MS-SQL verwendet * als Platzhalter, MySQL stattdessen das Prozentreichen (%).

    Diese Abfrage würde Produkt 2 und 3, also das Galaxy S4 und die Schutzfolie dazu, anzeigen.

    Grundsätzlich kann man in SQL alle aus anderen Programmiersprachen her bekannte Operatoren verwenden, wie AND, OR, NOT, >, <, >=, <=.

    Rechnen

    SQL beherrscht natürlich auch die Grundrechenarten. Will man zb wissen, wie viel Mehrwertsteuer auf die Artikel zu zahlen ist, multipliziert man einfach die Spalte mit 0,19:
    SELECT item_id, titel, price * 0.19 FROM items
    WHERE item_id = 1

    Das Ergebnis stimmt zwar, aber der Spaltenname ist nicht gerade optimal um diesen Wert zb in einer ASP.NET oder PHP-Anwendung weiterverarbeiten zu können. MySQL setzt hier als Spaltenname price * 0.19 und MS-SQL nummeriert mit Expr durch. SQL bietet jedoch die Möglichkeit, jedem Wert einen Alias zuzuweisen:
    SELECT item_id, titel,price * 0.19 AS mwst
    FROM items
    WHERE item_id = 1

    Darüber hinaus sind noch weitere Funktionen implementiert, die dem Programmierer lästige Grundschulrechnungen ersparen:
    SELECT AVG(price) as averagePrice
    FROM items;

    Würde genau ein Ergebnis, nämlich den Durchschnittspreis aller Artikel liefern. Es gibt noch mehr solcher Funktionen, etwa
    - COUNT(column): Zählt die Datensätze der Spalte column
    - MAX(column): Gibt den höchsten Wert der Spalte column aus
    - MIN(column): Gibt den niedrigsten Wert der Spalte column aus
    - SUM(column): Addiert alle Werte der Spalte column

    Diese Funktionen fassen die Werte in einer Spalte jeweils auf unterschiedliche Art zusammen und liefern daher nur einen Wert als Ausgabe. Man nennt sie Aggregatfunktion. Sie sind nicht mit Skalarfunktionen wie zb DateDiff() zu verwechseln, die sich jeweils nur auf den Wert eines einzelnen Datensatzes beschränken.

    Sortieren

    Gerade bei vielen Datensätzen möchte man diese sortieren. Bei den Beispieltabellen möchte man als Shopinhaber zb vor der nächsten Bestellung wissen, von welchen Artikeln am wenigsten auf Lager sind um von diesen Artikeln neue zu bestellen. Sortiert wird in SQL mit ORDER BY:
    SELECT item_id, title, stock
    FROM items
    ORDER BY stock;


    Name:  sql-order-by-asc.png
Hits: 406
Größe:  5,5 KB

    Die Datensätze wurden aufsteigend nach stock sortiert. Man kann die Sortierreihenfolge natürlich auch ändern. Das macht zb Sinn, wenn man über eine Rabattaktion nachdenkt und dafür die Preise der teuersten Artikel aufgelistet haben will:
    SELECT item_id, title, price
    FROM items
    ORDER BY price DESC;


    Name:  sql-order-by-desc.png
Hits: 384
Größe:  5,5 KB

    DESC ist eine Abkürzung für descending und heißt übersetzt absteigend. Lässt man DESC weg wird automatisch aufsteigend sortiert (ASC = ascending = aufsteigend). Im oberen Beispiel wo die Artikel mit den geringsten Stückzahlen aufgelistet werden sollen wäre folgende SQL-Abfrage also ebenfalls korrekt:
    SELECT item_id, title, stock
    FROM items
    ORDER BY stock ASC;

    Da Programmierer aber generell faul sind kann man sich einfach merken: Bei absteigender Sortierung braucht man nichts weiter außer den Spaltenname anzugeben, nur bei aufsteigender Sortierung DESC.

    Gruppieren

    Manchmal macht es Sinn, Datensätze nach bestimmten Spalten zu gruppieren. In diesem Beispiel könnte man zb für eine Statistik über die Kunden ermitteln, wie viele Kunden aus welcher Stadt kommen. Das geht mit GROUP BY:
    SELECT city, COUNT(*) AS customer_count
    FROM customer
    GROUP BY city;


    Name:  sql-group-by.png
Hits: 376
Größe:  2,6 KB

    Hier ist das natürlich wieder etwas unspektakulär da nur 3 Datensätze vorhanden sind. In einem Shop wo pro Tag ein paar hundert Kunden einkaufen und am Monatsende solch eine Statistik erstellt werden soll sieht das aber schon ganz anders aus.

    Sonderfall Aggreatfunktionen:
    Will man eine Aggreatfunktion wie zb SUM(column) in eine Bedingung für eine Gruppierung einbinden, wird HAVING statt WHERE genutzt. Als Bedingung darf HAVING daher nur Spalten beinhalten, die in GROUP BY verwendet wurden. HAVING muss hinter GROUP BY und vor ORDER BY (falls verwendet) stehen. Da HAVING vom SQL-Server ziemlich gegen Ende abgearbeitet wird, dürfen Aliase aus dem SELECT-Teil die im WHERE-Teil nicht verwendbar sind benutzt werden. Nach HAVING kann mit den erlaubten Spalten jede normale Bedingung stehen die auch in WHERE gültig ist (AND, OR, <, > etc).

    Beispiel:
    Aus dem obigen Beispiel wo die Kunden nach Stadt gruppiert werden wollen wir nur Städte anzeigen in denen mehr als 1 Kunde bestellt hat:

    SELECT city, COUNT(*) AS customer_countFROM customer
    GROUP BY city
    HAVING customer_count > 1;

    Ergebnis:

    Name:  group-by-having.png
Hits: 398
Größe:  1,8 KB


    Joins

    Equal-Join

    Hat nichts mit Joints zutun. Joins stellen Verknüpfungen zwischen mehreren Tabellen her. In diesen Beispieltabellen macht ein Join Sinn, wenn man zb den Preis der Bestellung unseres ersten Kunden (customer_id = 1) wissen möchte. In der Tabelle orders liegt die ID des Kunden (customer_id) und die ID des Produkts (item_id) vor. Ohne Joins müsste man eine SELECT-Abfrage für die item_id erstellen und anschließend eine zweite, welche über diese ID den Preis aus der items-Tabelle ausließt. Joints sei Dank ist so eine Murkserei nicht nötig:
    SELECT items.price
    FROM items, orders
    WHERE orders.item_id = items.item_id
    AND orders.customer_id = 1;

    Man sieht sofort zwei Unterschiede zu allen bisherigen Abfragen: Die Tabellennamen werden überall explizit genannt (items.price) und im FROM-Teil befinden sich zwei Tabellen. Die Benutzung der Tabellennamen hat den Grund, dass es öfter mal vorkommt, dass in den verwendeten Tabellen zwei oder mehr Spalten gleich heißen (zb 2x id). In dem Fall weiß der Datenbankserver logischerweise nicht, welche von beiden Tabellen man meint. Daher gibt man diese immer mit an.
    Die Tabellen mit denen der Join ausgeführt werden soll, werden im FROM-Teil mit Komma getrennt angegeben. Der eigentliche Join ist in diesem Fall die WHERE-Bedingung (grün). Wir wollen nur den Preis von dem Produkt, die der Kunde #1 gekauft hat. Daher müssen item_id aus der orders-Tabelle und item_id aus der items-Tabelle gleich sein. In der orders-Tabelle wollen wir nur Bestellungen von Kunde #1, daher eine zusätzliche Bedingung customer_id = 1.

    Die Bedingung des Joins ist sehr wichtig. Der SQL-Server ordnet jedem Datensatz der ersten Tabelle allen Datensätzen der zweiten Tabelle zu, die Eingrenzung findet nur über die Bedingung(en) des Joins statt. Verpatzt man diese, bekommt man bei einer großen Datenbank schnell mal verdammt viele Datensätze angezeigt. Im dümmsten Fall schießt man damit irgendwas ab.

    Um das zu demonstrieren, lasse ich die Join-Bedingung mal bewusst weg und nehme Kunde #3. Wieso? Kunde #3 hat zwei Artikel bestellt (4 und 3).
    Wir bekommen also 2 (Bestellungen) * 4 (Produkte in items) = 8 Datensätze:

    Name:  join-failed.png
Hits: 393
Größe:  1,7 KB

    Dazugehörige Abfrage:
    SELECT items.priceFROM items, orders
    WHERE orders.customer_id = 3;

    Und das ist hier noch eine vergleichsweise kleine Tabelle. In größeren Datenbanken bekommt man da schnell mal Datenmengen die jenseits von gut und Böse sind.
    Es gibt auch noch mehrere Arten als den Equal-Join (zb Left-Join). Das hier ist Vordergrundmäßig eine Zusammenfassung für meine Klasse. Daher das ganze auch als Einführung und nicht als komplettes SQL-Grundwissen ansehen, denn da gehört noch mehr dazu.


  2. The Following 6 Users Say Thank You to DMW007 For This Useful Post:

    Devon (27.06.2013), DiscoDieter (03.01.2014), Gangstersheep (16.06.2013), Itsab (16.06.2013), Saad (16.06.2013), Silvatris (16.06.2013)

  3. #2
    Avatar von Snees
    Registriert seit
    18.11.2011
    Beiträge
    1.001
    Thanked 590 Times in 319 Posts

    Standard AW: Einführung in SQL SELECT-Abfragen

    Nur um kurz auf die Tabellenstruktur einzugehen (hier eher unwichtig, vielleicht interessiert es aber jemanden):

    Die Anzahl der Artikel werden normalerweise nicht in der Artikel-Tabelle gespeichert, sondern in einer Lager-Tabelle, in die Artikel-Tabelle wird dann nur die Lager-ID eingetragen.

    Bestellungen werden auch etwas anders gespeichert. Dazu gibt es eine Kopf- und Segment-Tabelle. In der Kopf-Tabelle steht, welcher Benutzer welche Bestellung getätigt hat, in der Segment-Tabelle stehen dann die einzelnen Artikel der Bestellung. (macht SAP übrigens auch so )

Ähnliche Themen

  1. Antworten: 5
    Letzter Beitrag: 05.01.2017, 09:31
  2. Wozu gibt es Cable Select bei Ide Festplatten?
    Von Tony Montana im Forum Hardware
    Antworten: 1
    Letzter Beitrag: 22.03.2014, 07:48
  3. Antworten: 11
    Letzter Beitrag: 07.11.2013, 21:37
  4. [PHP] Update Select Problem
    Von ZarneXxX im Forum PHP
    Antworten: 9
    Letzter Beitrag: 18.09.2013, 16:00
  5. C# webBrowser dropdown select
    Von Bl1zz4rD im Forum .Net
    Antworten: 2
    Letzter Beitrag: 05.04.2013, 12:08

Stichworte

Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.