SQL


weiß ned :slight_smile:

is ja auch ned unbedingt sinn und zweck der sache euch da so mit meinen probs zu belagern ^^

EDIT:
ich hoff SQL is das schlimmste bei der Klausur


doch, das ist der sinn des forums


Ich finde es gut, wenn ich was erklären kann, dann merk ich, dass ichs anscheinend kann :smiley:
Also: stell ruhig deine Fragen :wink:
Und wie gesagt wurde: dafür ist das Forum da.


:slight_smile:

dann mach dich aber auf was gefasst :-p ich hab bestimmt noch unendlich viele fragen .


und schom hab ich die nächste frage:

Wir benötigen eine Liste aller Städte, die mit ‘E’ beginnen und in denen mehr als zwei
Kunden wohnen. Neben dem Städtenamen ist dann die Anzahl der Kunden interessant.
Die Sortierung erfolgt nach der Anzahl absteigend.

SELECT stadt
, COUNT() AS anzahlkunden
FROM kunde
WHERE stadt LIKE ‘E%’
GROUP BY stadt
HAVING COUNT(
) > 2
ORDER BY anzahlkunden DESC;

also ich habs per zufall richtig gemacht (aber man will ja nix dem zufall überlassen in der klausur :wink: )
wieso muss man zuerst die Stadt mit e rausfiltern und dann nach dem gruppieren erst die anzahl der kunden, die größer ist als 2 ?

EDIT: und seh ich es richtig, dass das GROUP BY jetzt da ist um zu sagen, dass man die anzahl pro stadt will? und nicht insgesamt?


Du betrachtest nur die Tupel bei denen die Stadt mit E anfängt, dann gruppierst du nach Stadt und machst aus deiner Tabelle für jede Stadt mit dem gleichen Namen kleine Untertabellen.
Dann im count(*) zählt er die Anzahl der Zeilen pro Gruppierung und da du nur die willst, in denen es mehr als 2 Kunden pro Stadt gibt, baust du die Bedingung > 2 ins Having ein.

Wie group by und having funktionieren siehst du sonst auch gut und in meinem Post über top-n

/edit

Ganz genau.


ahh jetz :slight_smile: hab ichs glaub ich

Also quasi weil wenn ich erst count* mache es ja noch nicht gruppiert ist und es somit alle kunden zählt anstatt die kunden pro stadt?


yup genau.

Der erste Satz ist etwas verwirrent, daher nochmal ausformuliert.

Mit count(*) würdest du sonst alle Kunden bekommen deren Stadt mit E anfängt.
Wenn du zusätzlich das group by machst, gruppiert count (und übrigens alle weiteren aggregatsfunktionen wie max, min) über die gruppe.


Ganz genau,
außerdem würde dann das count(*) im select stehen, denn die Having-Klausel bezieht sich immer auf die Gruppierung aus dem group by; sprich kein having ohne group by

/edit

Stimmt das ist auch noch ein guter Punkt

select count(*)
from kunden
where Stadt like ‚E%‘

würde einem nur ein Tupel ausgeben mit einer Spalte count(*), das die Anzahl der Kunden aus Städten mit E enthält.


wow :smiley: was ich heute für erkenntnisse hab, hätt ich ned gedacht, dass ich die noch kriege.

Jetz hab ich nur noch die TOP n aufgabe vor mir und versteh nur bahnhof … naja der Abend is jung :confused:


Top n abfragen laufen immer nach dem gleichen Schema ab und sind wirklich nicht kompliziert.
Zuerst baust du einen View mit den relevanten Daten auf und machst dann deine top-n Abfrage die IMMER für ALLES genau gleich aussieht.


echt?

hmm vllt sollt ichs einfach auswendig lernen … weil verstehn tu ichs irgendwie nich :blush:

SELECT COUNT() AS rang
, f1.firmenname
, f1.umsatz
FROM firmenumsatz f1
, firmenumsatz f2
WHERE f1.umsatz <= f2.umsatz
GROUP BY
f1.strasse
, f1.hausnummer
, f1.plz
, f1.stadt
, f1.firmenname
, f1.umsatz
HAVING COUNT(
) <= 10
ORDER BY rang ASC;

jetz häng ich schon an dem f1 und f2, was soll das? und wieso muss f1.umsatz kleinder sein als f2.umsatz?


schau dir mal mein Beispiel hier an, dann wirds dir hoffentlich klarer


Schau mal in einen der parallelen Threads hier. In einem (ziemlich am Ende) hat coMar das ganze mal bildlich hingeschrieben. Da sieht man eigentlich ganz gut was genau passiert.

Kurz: du machst das Kreuzprodukt aus Firmenumsatz und Firmenumsatz (ja, mit sich selber) und suchst dann nur die Tupel, in denen die <= Bedingung gilt. Dadurch entsteht so Dreieck-Schema, die Firma mit dem meisten Umsatz kommt nur in einem Tupel vor (<=), die anderen entsprechend öfters. Das ganze kombiniert mit group by und count(*) liefert dir den Rang.

Wie gesagt, bildlich macht das ganze wesentlich mehr Sinn. Vielleicht auch einfach mal selber aufmalen :slight_smile:

Edit: genau der Link :smiley:


Du kannst auch mal einen Blick in die Musterlösung des 8. Übungsblattes werfen. Dort wird das ganze eigentlich ziemlich ausführlich erklärt und auch beschrieben, was der Sinn des <= ist - nämlich diejenigen zu finden, die mehr oder genauso viel Umsatz haben, wie eine bestimmte Firma.

Die Firma mit dem meisten Umsatz hat foglich nur genau eine Firma, die mehr oder genauso viel Umsatz macht, wie sie selbst: Sich selbst. Die mit dem zweimeisten Umsatz haben dann zwei Firmen(sich selbst und die mit dem meisten) etc. Und dann Gruppierst du das nach den Firmen und hast dann für jede Firma eine Art Untertabelle, die so viele Zeilen hat, wie es Firmen gibt, die einen größeren Umsatz haben. Und dann musst du nur noch die Zeilen zählen und weißt, welche die Top N-Firmen sind.


Hat dir schon mal jemand gesagt dass es sehr viel lehrreicher ist Dinge zu erklären als sie erklärt zu bekommen? :wink:

Dass SQL ordentlich drankommt hoffe ich auch, aber ich möchte wetten da lauern noch ein paar echt fiese Auswendiglern-Fragen auf uns…

Könnte man übrigens vom Ergebnis her genauso gut schreiben als:

SELECT stadt
 , COUNT(*) AS anzahlkunden
 FROM kunde
 GROUP BY stadt
 HAVING COUNT(*) > 2 AND
  stadt LIKE 'E%'
 ORDER BY anzahlkunden DESC;

Nur im ersten Fall wird halt erst nach Stadt gefiltert und dann gruppiert, im letzten andersherum.


Hey, ich greif das da nochmal auf, hab nämlich ne frage dazu // parallelthreads hab ich schon durchgelesen, aber so ganz is meine frage noch nicht gelöst oder zumindest hab ichs noch nich verstanden.

Frage: Wenn ich jetz ja zähle und dann nur die nehme die kleiner gleich 10 sind und danach erst sortiere wo ist denn dan sichergestellt, dass ich nur die firmen mit dem größten umsatz bekomme?
Weil hier wird ja gar nicht nach umsatz sortiert, oder doch? und wenn doch wie ist es sichergestellt, dass es dann die ersten 10 obersten firmen abzählt?


HAVING COUNT(*) <= 10
legt fest dass du nur die Gruppierungen bekommst die maximal 9 größere Tupel auf der zweiten Hälfte (f2) enthalten und sich selbst. Also die 10 besten.

Zur Erinnerung die Abfragereihenfolge ist:

  1. from
  2. where
  3. group by
  4. having
  5. select
  6. order by

Aber ich seh auch gerade, dass es dir in dem anderen Thread schon erklärt wurde.


Tja das ist ja der Trick, der durch den Autojoin angewandt wird ;).

Du joinst eine Tabelle mit sich selbst und übernimmst aber nur die Tupel, in denen der Umsatz einer Firma kleiner oder gleich denen einen anderen Firma ist. Das heißt es gibt dann für jede Firma f1 mehrere Tupel in der Relation, die sich alle vor allem darin unterscheiden, dass eine andere Vergleichsfirma mehr Umsatz macht als sie selbst.

Das ganze sieht jetzt vereinfacht so aus:

F1 | F2(mehr Umsatz)
a a
a b
a c
a d
b b
c b
c c
c d
d b
d d

Und wennd du jetzt diese Tabelle nach den Firmen grupierst, dann kannst du quasi an den Zeilen abzählen, wie viele Firmen es gibt, die mehr(oder genausoviel Umsatz) machen. Und die Firma, die nur eine Firma über sich hat, ist eben die Firma, die den meisten Umsatz hat, die die zwei Firmen über sich hat, den zweitmeisten etc.

Du musst also nicht nach dem Umsatz sortieren, weil dich der gar nicht wirklich interessiert. Dich interessiert ja ersz mal nur, welche Firmen am meisten Umsatz haben. Das heißt in Top-N: Für welche Firmen gibt es nur wenige, die mehr Umsatz machen als sie selbst. Und das geschieht eben durch den Autojoin, die Gruppierung und das abschließende Zählen der Zeilen.


okay danke. ich glaub jetz ist es mir klarer :=)