ERLEDIGT
JA
JA
ANTWORTEN
6
6
ZUGRIFFE
2418
2418
EMPFEHLEN
-
Guten Tag,
ich hätte mal wieder ein Oracle-SQL-Problem und hoffe hier kann mir jemand einen hilfreichen Tipp dazu geben:
Also folgende Tabellenstruktur hab ich:
ID___ version___nummer
1____1________1542
1____2________ 8185
2____1________1547
Anforderung wäre nun folgens:
ID__älteste_versionsnummer___neueste versionsnummer
1___1542___________________ 8185
2___1547___________________ 1547
Also wenn die Version gleich der maximalen Version für diese ID ist, dann soll der Wert in die eine spalte, wenn die Version gleich der minimalen Version für diese ID ist, dann entsprechend in die zweite.
Verständlich? jemand ne idee wie man das machen könnte?
ich hab schon probiert mitaber da bekomme ich den fehler das hier keie agregatfunktion erlaubt sei. mitCode :1
where version = min(version)
bekomme ich die jeweils großte und kleinste version nebeneinander, aber wie kann ich da jetzt die nummer dazu bringen?Code :1 2 3 4 5
select id, min(version) as a, max(version) as b from tab group by id
vlgGeändert von Sabine_81 (27.10.08 um 14:05 Uhr)
-
Hi,
zuallererst musst du darauf achten, dass jede Kombination aus ID und Version eindeutig ist. Dann kriegst du die passenden Werte zB so raus:
Code :1 2 3 4 5 6 7 8
select x.id, minv.nummer as minnummer, maxv.nummer as maxnummer from (select id, min(version) as a, max(version) as b from tab group by id ) as x, tab as minv, tab as maxv where x.id = minv.id and x.a = minv.version and x.id = maxv.id and x.b = maxv.version
Afair ginge es auch mit Hilfe einiger OLAP-Funktionen, aber die hab ich grad nicht im Kopf.
-
danke schonmal...
ich habe es jetzt damit probiert... bekomme aber einen fehler: "sql_befehl wurde nicht korekkt beendet" und das "as" nach der klammer wird als falsch angezzeigt. ich hab al testweise mal alle drei "as" weg gelassen, dann bekomme ich den fehler das maxv.version ein ungültiger bezeichner sei...
-
oh, stimmt, Oracle mag da kein "as". Aber wenn ich das weglasse, funktionierts bei mir:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
SQL> create table tab( id integer not null, version integer not null, nummer integer not null, primary key( id, version ) ); SQL> insert into tab values( 1, 1, 1542); SQL> insert into tab values( 1, 2, 8185 ); SQL> insert into tab values( 2, 1, 1547 ); SQL> select x.id, minv.nummer as minnr, maxv.nummer as maxnr 2 from ( 3 select id, min(version) as a, max(version) as b from tab group by id 4 ) x, 5 tab minv, tab maxv 6 where x.id = minv.id and x.a = minv.version 7 and x.id = maxv.id and x.b = maxv.version; ID MINNR MAXNR ---------- ---------- ---------- 1 1542 8185 2 1547 1547
-
ohje... ich nehm alles zurück...
hab "tab" einfach stehen lassen und da nicht den namen meiner tabelle eingetragen... *schäm* sorry...
also es funktionierts ganz prima
ganz ganz ganz vielen lieben herzlichen Dank
-
27.10.08 15:30 #6
Zu Vollständigkeit hier nochmal eine Lösung mit den Analytischen Funktionen und eine Performancebetrachtung der beiden Lösungen:
Code sql:1 2 3 4 5 6 7
SELECT x.id, minv.nummer AS minnr, maxv.nummer AS maxnr FROM ( SELECT id, MIN(version) AS a, MAX(version) AS b FROM tab GROUP BY id ) x, tab minv, tab maxv WHERE x.id = minv.id AND x.a = minv.version AND x.id = maxv.id AND x.b = maxv.version;
Für diese Lösung berechnet Oracle einen mehr oder weniger komplexen Ausführungsplan und kommt dadurch auf 118 Bytes "Aufwand" und muss 9 Datenblocks lesen.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 118 | 3| | 1 | NESTED LOOPS | | 2 | 118 | 3| | 2 | NESTED LOOPS | | 2 | 98 | 2| | 3 | VIEW | | 2 | 78 | 1| | 4 | HASH GROUP BY | | 2 | 12 | 1| | 5 | INDEX FULL SCAN | SYS_C0063610 | 3 | 18 | 1| | 6 | TABLE ACCESS BY INDEX ROWID| TAB | 1 | 10 | 1| |* 7 | INDEX UNIQUE SCAN | SYS_C0063610 | 1 | | 1| | 8 | TABLE ACCESS BY INDEX ROWID | TAB | 1 | 10 | 1| |* 9 | INDEX UNIQUE SCAN | SYS_C0063610 | 1 | | 1| ----------------------------------------------------------------------------- Statistics ----------------------------- 9 consistent gets
Mit analytischen Funktionen würde die Lösung wie folgt aussehen:
Code sql:1 2 3 4 5 6 7
SELECT id, MIN(nummer) keep (dense_rank FIRST ORDER BY version) AS minnr, MAX(nummer) keep (dense_rank LAST ORDER BY version) AS maxnr FROM tab GROUP BY id;
Der Ausführungsplan ist einfacher und die Performance besser, da nur 2 Blöcke gelesen werden und die "Kosten" nur bei 20 Bytes liegen:
Code :1 2 3 4 5 6 7 8 9 10 11 12
---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 20 | 1| | 1 | SORT GROUP BY NOSORT | | 2 | 20 | 1| | 2 | TABLE ACCESS BY INDEX ROWID| TAB | 3 | 30 | 1| | 3 | INDEX FULL SCAN | SYS_C0063610 | 3 | | 1| ---------------------------------------------------------------------------- Statistics ---------------------------------------------------------- 2 consistent gets
liebe Grüße
Exceptionfault (http://exceptionfault.de)
Never say: "Always"! Always say: "Never say never"! - Tom Kyte @ Ask Tom Live in Berlin 2008
-
vielen Dank für den vergleich. ich habe die zweite Version auch mal ausprobiert, funktioniert auch sehr gut.
da es bei mir im moment nicht sehr viele datensätze gibt, bemerke ich perfomancemässig aber aktuell keinen unterschied. aber prima, dass ich diese version jetzt auch noch kenne :-D
Ähnliche Themen
-
Selektion eines nicht belegten Wertes innerhalb eines Bereiches (Oracle 10g)
Von TimoTH im Forum Relationale DatenbanksystemeAntworten: 2Letzter Beitrag: 06.10.10, 16:42 -
Konstruktor mit Übergabe eines Wertes
Von voelzi im Forum C/C++Antworten: 1Letzter Beitrag: 21.11.09, 21:05 -
Excel 2007, Abfrage eines Wertes eines Liste und einfügen von Feldern
Von ChriFlex im Forum Office-AnwendungenAntworten: 1Letzter Beitrag: 26.06.08, 12:41 -
Übergabe eines Wertes
Von minlok im Forum .NET ArchivAntworten: 0Letzter Beitrag: 17.03.05, 09:54 -
Ausdruck eines Wertes bei Anlegen eines neuen Datensatzes
Von realmontanakid im Forum .NET ArchivAntworten: 3Letzter Beitrag: 19.10.04, 11:02





Zitieren
Login





