select name, verein, ergebnis, disziplin
from (
select name, verein, ergebnis, disziplin, row_number() over (partition by verein order by ergebnis desc) as rn
from sportergebnisse
) t
where rn <= 5
order by verein, ergebnis desc;
Die Abfrage geht davon aus, dass ein höheres Ergebnis ein besseres ist.
Wenn Du bei den “die 5 Besten” auch welche mit der gleichen Wertung drin haben willst (es dann aber mehr als 5 werden können), nimm dense_rank() anstatt row_number()
hatte die Musterbezeichnungen so gewählt dass ich die Orginal Bezeichnungen nur rein kopieren mußte aber irgend wie klappt das nicht.
hab die Abfrage danach so vereinfacht dass ich nur noch Daten aus zwei Tabellen benötigte aber das hat auch nicht funktioniert.
die blose Abfrage und Sortiering Funktioniert korrekt, auch die row_ number Spalte wird korrekt gebildet.
Nnur sie Selectierung nach der rn bringe ich nicht auf die Reihe
select shooters.surname as Name,
shooters.forename as Vorname,
shooters.club as Verein,
journal.results as Ergebnis,
ROW_NUMBER() OVER (partition by shooters.club ORDER BY journal.results desc) as Platz
from home.journal,
home.shooters
where journal.shooters_id = shooters.shooters_id
and journal.event_status = ‘finished’
and journal.shooters_id >0
group by name,verein,vorname
order by Verein, Ergebnis desc
Es fehlt formal ein Group by “results”, geht vermutlich trotzdem nur, weil postgres schlau ist.
Das Group By … selbst ist insgesamt eigentlich auch überflüssig.
Das GROUP BY ist falsch und wird einen Fehler liefern - ist aber auch unnötig mit einer Window Funktion.
Du musst nur die aktuelle Abfrage in eine Sub-Query packen, dann klappt das:
select name, vorname, verein, ergebnis, platz
from (
select shooters.surname as Name,
shooters.forename as Vorname,
shooters.club as Verein,
journal.results as Ergebnis,
ROW_NUMBER() OVER (partition by shooters.club ORDER BY journal.results desc) as Platz
from home.journal
join home.shooters ON journal.shooters_id = shooters.shooters_id
where journal.event_status = 'finished'
and journal.shooters_id > 0
) t
where platz <= 5
order by Verein, Ergebnis desc;
Ich habe Deine veralteten impliziten Joins gleich durch einen modernen expliziten JOIN Operator ersetzt.
Die Bedingung “and journal.shooters_id > 0” sieht etwas merkwürdig aus. Gibt es denn überhaupt Shooter mit der ID=0? Wenn, nicht, dass ist das überflüssig da der JOIN solche Datensätze ja eliminieren würde. Sieht schwer danach aus, als würde da ein Foreign key fehlen.
@castorp, das mit dem “veraltet” kommt auf den Punkt, ich hab seit 25 Jahren nichts mehr mit SQL zu tun und das Veraltete war mir eben noch etwas in Erinnerung. Versuche nun da Bedarf entstanden ist mich wieder etwas einzulesen und hoffe dass ich mich vertrauensvoll an euch wenden darf.
Weiß ich wohl, aber ich war und bin kein Entwickler sondern nur ein ahnungsloser Nutzer der damals und heute wieder, Auswertungen braucht. So gings für mich eben einfacher. Ich wußte damals nicht mal wie man UNIX SQL schreibt, aber meine Kalkulationen haben auf den, Pfennig damals, gestimmt.
Ich wollte es nur erwähnen, weil ich immer wieder Leute treffe, die denken das der JOIN Operator was “ganz neues” wäre.
Einige verbreitete Datenbanksysteme haben das auch sehr lange nicht unterstützt (Oracle, SQL Server). Und in der Oracle Community gibt es noch einige Benutzer die sich immer noch weigern das zu verwenden weil es ganz am Anfang als Oracle das vor rund 15 Jahren eingeführt hat ein paar Bugs mit der Syntax gab.
Leider muss ich auch Postgres einen kleinen Vorwurf machen, weil in der Dokumentation praktisch alle Beispiele implizite joins verwenden und nicht den expliziten JOIN Operator.
Die impliziten joins haben das Problem, dass sie leicht in einem ungewollten cross join resultieren weil es kein Syntaxfehler ist die join Bedingung zu vergessen. Deswegen empfehle ich immer wo es nur geht, den “modernen” JOIN Operator zu verwenden.