sql-abfrage
-
Hallo,
wie mache ich folgendes am besten?
Ich habe eine Tabelle ähnlich dieser:create table test ( lfnr int, mitglied int, b int, c int, primary key (lfnr) );
lfnr ist laufende nummer also eindeutig.
in test können jetzt mehrere einträge zu jedem mitglied drinstehen, so zum beispiel:
lfnr mitg a b
1 10 10 5
2 10 7 6
3 20 3 9
4 20 5 8so, und jetzt endlich zu der frage:
ich möchte für alle eingetragenen mitglieder die a und b mit der jeweils höchsten laufenden nummer.
hier wäre das ergebnis:
mitg a b
10 7 6
20 5 8eine möglichkeit wäre ja:
select * from test where lfnr in (select max(lfnr) from test group by mitglied);
aber ist das die beste?witzig, als ich angefangen habe zu schreiben, da bin ich noch nicht auf die query gekommen, mal sehen, vielleicht habt ihr ja was besseres.
jenz
-
Hi,
was heisst besser? Du müsstest dir mal den Ausführungsplan anzeigen lassen, damit du gucken kannst, was deine DB unter Haube tut.
Allerdings scheint dein Statement schon zu passen, ich wüsst ad hoc auch nichts anderes.
-
ja, was heißt besser. gut frage!
zum einen finde ich das statement etwas holprig.
zum anderen hatte ich gedacht, dass das bestimmt eine anfrage ist, die recht häufig so an datenbanken gestellt wird.
eine tabelle in mehrere subsets unterteilen und dann jeweils eine zeile liefern.
gerade bei historien sollte das doch öfter vorkommen, oder?das hier schmeißt postgres aus:
Hash Join (cost=39.15..69.16 rows=200 width=28) Hash Cond: (public.t1302_locker_use.lfnr = "IN_subquery".max) -> Seq Scan on t1302_locker_use (cost=0.00..23.10 rows=1310 width=28) -> Hash (cost=36.65..36.65 rows=200 width=4) -> HashAggregate (cost=34.65..36.65 rows=200 width=4) -> HashAggregate (cost=29.65..32.15 rows=200 width=8) -> Seq Scan on t1302_locker_use (cost=0.00..23.10 rows=1310 width=8)
finde ich doch etwas viel.
-
Hi,
zugegeben, ich bin jetzt kein Experte, aber ich wüsste auch nicht, was die Alterantive sein sollte?
Fakt ist, dass du auf jeden Fall die gesamte Tabelle durchsuchen musst, um überhaupt den Höchstwert zu bestimmen.
EDIT: Vergiss das mit dem Index. Bei sowas sind Statistiken ganz hilfreich, die du mit http://www.postgresql.org/docs/8.1/static/sql-analyze.html erstellst. Danach sieht der Ausführungsplan so aus:
"Hash IN Join (cost=1.13..2.21 rows=2 width=16)" " Hash Cond: (test.lfnr = "IN_subquery".max)" " -> Seq Scan on test (cost=0.00..1.04 rows=4 width=16)" " -> Hash (cost=1.11..1.11 rows=2 width=4)" " -> Subquery Scan "IN_subquery" (cost=1.06..1.11 rows=2 width=4)" " -> HashAggregate (cost=1.06..1.09 rows=2 width=8)" " -> Seq Scan on test (cost=0.00..1.04 rows=4 width=8)"
-
naja, ich sozusagen eher auf der suche nach einer spzielformulierung, vielleicht ein "group by mitg_nr limit 1"
aber es geht ja erst mal