Ich finde es gut, wenn ich was erklären kann, dann merk ich, dass ichs anscheinend kann
Also: stell ruhig deine Fragen
Und wie gesagt wurde: dafür ist das Forum da.
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 )
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
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.
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.
hmm vllt sollt ichs einfach auswendig lernen … weil verstehn tu ichs irgendwie nich
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 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
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.
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:
from
where
group by
having
select
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.