10 höchste Werte

Guten Abend zusammen,

ich habe eine kurze Frage. Wie lautet denn der Befehl bei SQL, wodurch ich die 10 höchsten Werte einer beliebigen Spalte filtern und anzeigen lassen kann? Also die Spalte würde ich dann selber festlegen. Wäre super, wenn ihr mir weiterhelfen könntet.

MfG Markus

…der Befehl bei SQL, wodurch ich die 10 höchsten Werte …

Hallo Markus,

ohne Angabe der verwendeten Datenbank kann Dir keiner helfen, da dies eine standardisierte Funktion ist.

MfG Georg V.

Hi!

ohne Angabe der verwendeten Datenbank kann Dir keiner helfen,
da dies eine standardisierte Funktion ist.

Du meintest wohl k eine standardisierte Funktion, oder?

Grüße,
Tomh

PS: Schlagwörter TOP, MAX, etc. …

hallo markus

also, unter oracle geht das so (wenn auch nicht ganz sauber):

select *
from tabelle
where rownum b.spalte (+)
group by a.spalte
having count(b.spalte)

Hallo Erwin,

also, unter oracle geht das so (wenn auch nicht ganz sauber):
select *
from tabelle
where rownum b.spalte (+)
group by a.spalte
having count(b.spalte) SELECT * FROM (

SELECT spalte1, spalte2, …, rownum AS x
FROM tabelle
ORDER BY sortier_spalte
)
WHERE x

So etwas wie rownum gibt es auf so gut wie jedem RDBMS.

Und bezüglich analytical functions: Die sehen kompliziert aus, sind aber extrem mächtige Werkzeuge mit meist sehr guter Performance, wenn geht also unbedingt damit vertraut machen!

Gruß
Martin

hallo

So was von Dir, also ehrlich… Das ist nicht nur unsauber,
sondern schlicht und einfach falsch. Dieses Statement liefert
irgendwelche 10 Sätze, die dann nach spalte sortiert werden.
Nebenbei: Wenn Du Dich einmal bei uns vorstellen kommst - die
nächste Frage ist, warum das nur falsch sein kann.

hast du das auch verifiziert? ich habs jetzt mit unterschiedlichen tabellen und tabelleninhalten getestet und das ergebnis ist immer korrekt.

nur weil du vermutest, dass rownum auf eine bestimmte art und weise funktioniert, muss sich oracle noch lange nicht daran halten…

der witz ist, dass der oracle-optimizer erkennt, was ich vorhabe und automatisch zuerst sortiert und erst dann die where-klausel anwendet (also genau umgekehrt als normalerweise vorgegangen wird). zumindest unter oracle 10g klappt das problemlos. ob es mit anderen datenbanksystemen (inkl. älterer oracle-versionen) auch geht, wage ich allerdings zu bezweifeln. daher auch meine „unter oracle geht es so“ und „sehr unsauber“ (da auf oracle >= 10g beschränkt).

lg
erwin

Dann müsste ich nochmal genau nachschauen. Auf jeden Fall nennt es sich Query Analyzer. Ich vermute, dass es sich um Software von Microsoft handelt. Befinde mich nämlich im Studium und wir arbeiten damit in den Laboren (PC-Räumen).

Aber trotzdem schon mal vielen Dank für euren zahlreichen Antworten.

MfG Markus

Moin, Markus,

Wie lautet denn der Befehl bei SQL,
wodurch ich die 10 höchsten Werte einer beliebigen Spalte
filtern und anzeigen lassen kann?

den gibt es nicht. Die Ergebnisse einer Abfrage lassen sich in SQL sortieren, in diesem Fall würde absteigend sortiert werden, damit wäre der höchste Wert oben.

Manche Datenbankhersteller (MS Access, MySql) bieten außerhalb des Standards ein Prädikat wie top n oder first n an, die sich auf das Resultat einer Abfrage setzen lassen.

Auszug aus der Access-Hilfe:

_TOP n [PERCENT]

Gibt eine bestimmte Anzahl von Datensätzen zurück, die im oberen oder unteren Teil eines durch eine ORDER BY-Klausel angegebenen Bereichs liegen._
Gruß Ralf

Hi!

hast du das auch verifiziert? ich habs jetzt mit
unterschiedlichen tabellen und tabelleninhalten getestet und
das ergebnis ist immer korrekt.

Bei mir bringts bei drei Tabelle das korrekte Ergebnis, bei ca. 10 ein Falsches (mehr wollte ich nicht mehr testen) …

nur weil du vermutest, dass rownum auf eine bestimmte art und
weise funktioniert, muss sich oracle noch lange nicht daran
halten…

Doch, weil Rownum (in dieser Funktionalität) ja zu Oracle gehört wie der Bug zu Microsoft.

ob es mit anderen datenbanksystemen (inkl. älterer
oracle-versionen) auch geht, wage ich allerdings zu
bezweifeln. daher auch meine „unter oracle geht es so“ und
„sehr unsauber“ (da auf oracle >= 10g beschränkt).

Es sind ja genau diese _älteren_ Versionen, die zu diesem Rownum-Irrtum führten - und wie schon gesagt: auf MEINER 10g funktionierts nicht immer …

Einigen wir uns auf ein saubere Lösung:

select \*
from (select \* from tabelle order by spalte)
where rownum 

So sind wir nun Versionsunabhängig ...

Grüße,
Tomh

Hallo Erwin,

So was von Dir, also ehrlich… Das ist nicht nur unsauber,
sondern schlicht und einfach falsch. Dieses Statement liefert
irgendwelche 10 Sätze, die dann nach spalte sortiert werden.
Nebenbei: Wenn Du Dich einmal bei uns vorstellen kommst - die
nächste Frage ist, warum das nur falsch sein kann.

hast du das auch verifiziert? ich habs jetzt mit
unterschiedlichen tabellen und tabelleninhalten getestet und
das ergebnis ist immer korrekt.

Also wenn das bei Dir so ist, dann handelt es sich um puren Zufall. Du solltest die gleichen 10 Sätze, aber halt unsortiert kriegen, wenn du die ORDER BY-Klausel weglässt. Das muss auch so sein, weil man dieses Konstrukt ja tatsächlich verwenden könnte, um irgendwelche 10 Sätze zu selektieren. Da will man dann sicher nicht, dass die DB im Hintergrund erst einmal 10 Mio. Sätze sortiert. Die WHERE Klausel wird IMMER vor dem (GROUP BY und dieser vor dem) ORDER BY ausgeführt. Die Sache mit „erraten was der Benutzer in Wirklichkeit will, auch wenn er mir das falsch sagt“ gibt’s nur bei MS (und treibt mich dort regelmässig zum Verzweifeln).

SQL\> create table tab1 as select object\_name
 2 from user\_objects order by object\_name;

Table created.

SQL\> create table tab2 as select object\_name
 2 from user\_objects order by created;

Table created.

SQL\> select \* from tab1 where rownum select \* from tab2 where rownum spool off

Ich denke das beweist meine Aussage, oder? Datenbank ist hier übrigens Oracle 10.2.0.3.

Liebe Grüße
Martin

interessante erkenntnis…
hallo

bazong
hab nochmal nachgeprüft. meine ursprüngliche lösung funktioniert tatsächlich nur in bestimmten fällen - meist, wenn man nach dem primärschlüssel sortiert, aber auch nicht immer.

hab das konstrukt bisher nur einmal in einem code von eine kollegen gesehen und war anfangs selber überrascht, dass das klappt. habe allerdings nur mit genau dieser tabelle und der gleichen order-by-klausel getestet. da das statement nachvollziehbar immer die richtigen werte geliefert hat, nahm ich ein verstecktes feature von oracle an.

sortiert man nach einer anderen spalte als dem primärschlüssel, kommt offenbar immer das zu erwartende ergebnis: die ersten paar zeilen, die oracle im datensegment findet, allerdings brav innerhalb der ergebnismenge sortiert.

was mich jetzt irrigiert ist, warum es manchmal klappt. die tabellengrösse scheint nicht relevant zu sein (zumindest nicht auf den ersten blick).

meine vermutung: wenn der optimizer aufgrund der statistiken entscheidet, dass ein normaler full table scann sinnvoller ist, dann funktioniert es nicht. die daten werden in der natürlichen reihenfolge gelesen. kommt der optimizer aber zum schluss, dass er zuerst einen full-index-scann macht (z.b. weil er das order-by über den index erschlagen will), dann klappt es - weil die daten schon vorsortiert gelesen werden und daher das order-by nix mehr tut.

insofern stimmt es schon, dass es eine unbrauchbare lösung ist, weil man von den indizes und den statistiken abhängig ist. in manchen spezialfällen aber durchaus sinnvoll. wie im oben erwähnten anwendungsfall meines kollegen - da wäre es aber auch nicht so schlimm, wenn die daten in falscher reihenfolge geliefert würden.

lg
erwin

hallo

habs im anderen posting schon geschrieben. du hast recht: in 99,99% aller fälle kommt das order by immer zuletzt und meine lösung liefert schrott.

in einigen spezialfällen wickelt der optimizer das order-by aber über einen full-index-scann ab (der index ist ja schon vorsortiert). und in genau diesen fällen kommt das order-by VOR der where-klausel (besser gesagt, die daten werden bereits vorsortiert gelesen un die order-by-klausel fällt weg). der index alleine reicht aber nicht - vermutlich müssen die statistiken auch passen, damit der optimizer diesen weg einschlägt.

meine testfälle waren leider ausnahmslos solche fälle, wesshalb ich der irrigen annahme war, ein verstecktes feature von oracle gefunden zu haben.

insofern revidiere ich meine aussage: die methode ist für produktivsysteme völlig unbrauchbar, da nicht deterministisch. in manchen spezialfällen aber leichter zu tippen und vermutlich für die datenbank ressourcenschonener. die lösung über die inline-view müsste meines erachtens nach mehr platz im temp-tablespace verbrauchen…

mea culpa - ich werde versuchen, in zukunft allgemeingültigere behauptungen aufzustellen.

lg
erwin

Hallo Erwin,

in einigen spezialfällen wickelt der optimizer das order-by
aber über einen full-index-scann ab (der index ist ja schon
vorsortiert). und in genau diesen fällen kommt das order-by
VOR der where-klausel (besser gesagt, die daten werden bereits
vorsortiert gelesen un die order-by-klausel fällt weg). der
index alleine reicht aber nicht - vermutlich müssen die
statistiken auch passen, damit der optimizer diesen weg
einschlägt.

Stimmt, an diesen Spezialfall hab ich gar nicht gedacht. Das Ganze verlässt sich aber - wie du eh schriebst - auf zwei Voraussetzungen: a) dass der Optimizer sich entscheidet, das Ganze rein über den Index abzuwickeln (was er schon einmal nicht tun kann, wenn Spalten, die nicht im Index enthalten sind, mitselektiert werden)
und
b) dass der Index physikalisch bereits (richtig) sortiert vorliegt. Das klingt jetzt vielleicht blöd, aber wenn sich morgen früh der DBA entscheidet, den Index ab sofort absteigend zu sortieren, weil das bei einer anderen Query ein Problem erschlägt, dann schaut man blöd aus der Wäsch’.

Übrigens liefert die Variante mit ROWNUM und ORDER BY auch das richtige Ergebnis, wenn die Daten in der Tabelle schon richtig sortiert vorliegen - das halte ich von den Voraussetzungen her auch schon fast für gleichwertig.

insofern revidiere ich meine aussage: die methode ist für
produktivsysteme völlig unbrauchbar, da nicht deterministisch.

Sag’ ich doch :wink:

in manchen spezialfällen aber leichter zu tippen und
vermutlich für die datenbank ressourcenschonener. die lösung
über die inline-view müsste meines erachtens nach mehr platz
im temp-tablespace verbrauchen…

Wenn der Optimizer intelligent ist, dann kann er mit dem Inline-View genau den gleichen Plan verwenden, wie mit deiner Lösung, allerdings halt nur dann, wenn auch die Voraussetzungen gegeben sind. Wenn dem nicht so ist, dann kommt er an einem (memory oder disk) sort ohnehin nicht vorbei. Einzige Alternative wäre da dann ein falsches Ergebnis.

mea culpa - ich werde versuchen, in zukunft allgemeingültigere
behauptungen aufzustellen.

Ich hab’ mich nur gewundert, weil das meiner bisherigen Erfahrung nach eigentlich ein Anfängerfehler ist. Wenn bei unseren Vorstellungsgesprächen einer allzu forsch mit seinen super SQL-Kenntnissen zu landen versucht, dann kriegt er als ersten Stolperstein genau diese Frage.

Die einzig falsche Antwort ist die, die Du da angeführt hast. Sogar ein „weiss ich nicht“ werten wir da deutlich besser… Wenn er natürlich eine beliebige richtige Antwort kennt, dann kommt der nächste Bomber mit Platzierungen unter Berücksichtigung von ex-aequo Plätzen (wenn da einer draufkommt, dass man nur die Zeilen mit kleineren/grösseren Werten zählen muss, dann hat er schon fast gewonnen).

Gruß
Martin

lg
erwin