PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Oracle/SQL-Übungsaufgabe


BattleRoyale
2020-05-26, 18:56:53
hi!
ich versuche mich atm in oracle/sql und habe probs mit einer übungsaufgabe.
mich würde interessieren wie ihr die lösen würdet. die musterlösung (siehe unten) wirft bei mir ein paar fragen auf.
da ja mehrere wege zum ziel führen würde mich interessieren wie ihr die (ggf. simpler) lösen würdet.

vom lernen her bin ich gerade bei dem bereich "group/having" etc.

die aufgabe:
Geben Sie den Bus aus, der am meisten Fahrten gefahren ist (fahrzeug_id, Anzahl_fahrten)! (ERM siehe unten)



Musterlösung mit fragen von mir. (bestimmt totale noob fragen :-) )

SELECT b.fahrzeug_id, COUNT(*)
FROM busse b, einsatzplan e
WHERE e.fahrzeug_id = b.fahrzeug_id
GROUP BY b.fahrzeug_id
HAVING COUNT(*) >= ALL(SELECT COUNT(*) FROM einsatzplan e2 GROUP BY e2.fahrzeug_id)

meine fragen:
warum wird die tabelle "busse" mit einbezogen? alle erforderlichen daten stehen doch in der tabelle "einsatzplan".

kann mir jemand mal schritt für schritt erläutern was hier bei der "having" klausel passiert?
having ansich ist mir ja klar. aber dieses konstrukt hier ist mir zu hoch.

Sephiroth
2020-05-26, 19:11:20
siehe https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Comparison-Conditions.html#GUID-828576BF-E606-4EA6-B94B-BFF48B67F927__CJAGAABC zum all operator

also quasi: das mit anzahl >= allen anzahlen aus dem subquery ... und somit das mit der höchsten.

BattleRoyale
2020-05-26, 21:04:07
>= all nicht nicht das prob (glaube ich :biggrin:)
mir will nicht in den kopf was er bei den beiden "counts" in der having klausel zählt. ;(

ich will gerne verstehen was da schritt für schritt passiert.
da ist bei mir der groschen noch nicht gefallen.

Gast
2020-05-26, 23:21:30
HAVING COUNT(*) >= gibt einfach den eintrag mit dem höchsten wert im querry ALL(SELECT COUNT(*) FROM einsatzplan e2 GROUP BY e2.fahrzeug_id) aus.

Sephiroth
2020-05-26, 23:30:15
in "HAVING COUNT(*) " bezieht sich das count auf das ergebnis der aggregationsfunktion aus dem select - anders ausgedrückt auf den wert der in der zeile stünde; da wird also nicht nochmal gezählt. das was da angegeben wird muss entweder eine aggregationsfunktion aus der select-klausel sein (gleicher ausdruck) oder eine spalte aus der group-by-klausel.

das count aus dem "all", sprich der rechten seite der having-klausel, ist ein eigenständiges subquery (kannste auch separat ausführen). da werden dann nur die anzahl der fahrten eines fahrzeugs selektiert, also z.b. drei zeilen mit 10, 7 und 3. und das "all" sagt dann: hey, nimm doch bitte alle bei denen die anzahl der fahrten >= 10 und >= 7 und >= 3 ist.

p.s.
schau dir den explain plan im sql developer an.

p.p.s.
ja, der join mit "busse" kann weg.

BattleRoyale
2020-05-27, 00:41:14
VIELEN DANK!

das count bei having bezieht sich auf das count aus der ergebnistabelle von group by.
ahhh okok das macht sinn :-)

langsam macht es klick!
wenn der join raus ist ist es auch schonmal viel übersichtlicher.

soweit klar. ABER eine frage hätte ich noch.
das ">=ALL" vergleicht also folgende tabellen miteinander (siehe anhang).

>=ALL zeigt all das an was true zurückgibt. richtig?
muss ich mir das so vorstellen das er alle miteinander vergleicht (siehe tabellen):
12 >= 12 true
12 >= 24 false also fällt links die 12 raus.
---
24 >= gibt bei 32 ein false zurück und fällt auch raus.
---
14 >= 12 true
14 >= 24 false fällt also raus
---
.
.
bei 32 ist dann bei jeden vergleich true und darum das ergebnis.

Sephiroth
2020-05-27, 23:04:12
>=ALL zeigt all das an was true zurückgibt. richtig?
muss ich mir das so vorstellen das er alle miteinander vergleicht (siehe tabellen):
12 >= 12 true
12 >= 24 false also fällt links die 12 raus.
---
24 >= gibt bei 32 ein false zurück und fällt auch raus.
---
14 >= 12 true
14 >= 24 false fällt also raus
---
.
.
bei 32 ist dann bei jeden vergleich true und darum das ergebnis.
ja genau, wobei man besser sagen sollte "überall true" oder "keines false" liefert.

und im schlechtesten fall hättest du n² vergleichsoperationen (n boolesche ausdrücke mit je n konjunktionen), weil jeder wert links mit allen werten rechts verglichen werden muss.

Matrix316
2020-05-28, 17:16:13
Diese Musterlösung sieht mir auch etwas kompliziert aus. ;)

Sumpfmolch
2020-06-11, 18:10:18
Ich hätte da vermutlich irgendwas in die Richtung

select fahrzeug_id, count(Fahrt_id)
from Einsatzplan
group by fahrzeug_id
order by count(Fahrt_id) desc
limit 1

hingeworfen...