newbii Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 Man, man, man... So doof hab ich mich schon lange nicht mehr gefühlt... Ich hab folgende Tabelle ID LAND_ID SPRACH_ID WERT DATUM 01 22 02 Wert1 01.01.2008 02 22 02 Wert2 02.01.2008 03 22 03 Wert3 01.01.2008 04 22 02 Wert4 03.01.2008 05 22 03 Wert5 05.01.2008 Ich brauch jetzt das neueste Datum mit dem entsprechenden Wert mit der LAND_ID 22 und der SPRACH_ID 02. Ich weiss es muss irgendwie mit MAX gehen, aber ich krieg es einfach nicht auf die Reihe... Danke für Eure Hilfe! Zitieren
alekz Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 so müßte es eigentlich funktionieren: select LAND_ID, SPRACH_ID, DATUM from tabelle where DATUM = (select max(DATUM) from tabelle) kann sein, dass es auch noch einfacher geht...ich stecke aber gerade auch nicht mehr so in SQL drin. EDIT: Vergiss es! hab die Frage falsch verstanden. Meine Lösung ist murks! Zitieren
Amstelchen Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 ungetestet: SELECT wert FROM tab WHERE LAND_ID 22 and SPRACH_ID 02 and DATUM = (select max(DATUM) from tab) das mit dem subselect stimmt schon so, weil DATUM = max(DATUM) kein korrektes gruppierendes aggregat ist. s'Amstel Zitieren
alekz Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 ungetestet: SELECT wert FROM tab WHERE LAND_ID 22 and SPRACH_ID 02 and DATUM = (select max(DATUM) from tab) das mit dem subselect stimmt schon so, weil DATUM = max(DATUM) kein korrektes gruppierendes aggregat ist. s'Amstel ich glaube die lösung wird aber nicht immer funktionieren. wenn nämlich das subselect ein datum zurückliefert das aktueller ist als alle datumswerte die du durch die einschränkung land 22 und sprach 02 erhältst, wird kein datensatz zurückgeliefert. in diesem beispiel liefert max(datum) den 05.01.08 zurück. dieses datum gibt es bei land_id = 22 und sprach_id = 02 nicht. daher ist die gesamte bedingung false. das gewünschte ergebnis soll aber vermutlich der datensatz mit der ID = 04 sein? EDIT: falls ich mit meiner Vermutung richtig liege, könnte man es auch so lösen (wobei ich die lösung nun auch nicht besonders schön finde): SELECT wert, datum FROM tabelle tab1 WHERE LAND_ID = 22 and SPRACH_ID = 02 and DATUM = (select max(DATUM) from tabelle tab2 where tab2.land_id = tab1.land_id and tab2.sprach_id = tab1.sprach_id) Zitieren
dbwizard Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 Man, man, man... So doof hab ich mich schon lange nicht mehr gefühlt... Ich hab folgende Tabelle ID LAND_ID SPRACH_ID WERT DATUM 01 22 02 Wert1 01.01.2008 02 22 02 Wert2 02.01.2008 03 22 03 Wert3 01.01.2008 04 22 02 Wert4 03.01.2008 05 22 03 Wert5 05.01.2008 Ich brauch jetzt das neueste Datum mit dem entsprechenden Wert mit der LAND_ID 22 und der SPRACH_ID 02. Ich weiss es muss irgendwie mit MAX gehen, aber ich krieg es einfach nicht auf die Reihe... Danke für Eure Hilfe! select max(datum), LAND_ID, SPRACH_ID from TEST GROUP by LAND_ID,SPRACH_ID HAVING LAND_ID=22 AND SPRACH_ID=2 --> 3-Jan-2008 22 2 Gruss Zitieren
dr.dimitri Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 Nur anstatt HAVING bitte WHERE verwenden. das ist ja grausam Dim Zitieren
alekz Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 aber mit der abfrage ist es nicht möglich sich die spalte wert zurückgeben zu lassen. seh ich das richtig? Zitieren
dbwizard Geschrieben 30. Januar 2008 Geschrieben 30. Januar 2008 Nur anstatt HAVING bitte WHERE verwenden. das ist ja grausam Dim Warum ? Zitieren
dr.dimitri Geschrieben 31. Januar 2008 Geschrieben 31. Januar 2008 Weil HAVING benutzt wird um eine Gruppe zu filtern. Dementsprechend ist auch die Reihenfolge der Ausführung. Bei einem WHERE wird vorher gefiltert, bei einem HAVING erst danach. Mal ein Beispiel: SQL> explain plan for SELECT TABELLE,SCHLUESSEL,MAX(SORTIERUNG) 2 FROM TBLSYNCHISTORY 3 GROUP BY TABELLE,SCHLUESSEL 4 HAVING TABELLE='TBL0200ALLGVERTRAG' AND SCHLUESSEL='1234567'; EXPLAIN PLAN ausgeführt. SQL> select * from table(dbms_xplan.display); ----------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 43 | 241K| | | | 1 | FILTER | | | | | | | | 2 | SORT GROUP BY | | 1 | 43 | 241K| | | | 3 | PARTITION RANGE ALL | | | | | 1 | 51 | | 4 | INDEX FAST FULL SCAN| TBLSYNCHISTORY_IX2 | 110M| 4524M| 173K| 1 | 51 | ----------------------------------------------------------------------------------------------- Wie Du siehst, wird ganz zum Schluss nochmal extra gefiltert. Es wurden also (unnötiger weise) alle Daten verarbeitet (zur Info: Die im Plan angegebenen Zahlen sind korrekt!). Jetzt die korrekte Schreibweise mit WHERE: SQL> explain plan for SELECT TABELLE,SCHLUESSEL,MAX(SORTIERUNG) 2 FROM TBLSYNCHISTORY 3 WHERE TABELLE='TBL0200ALLGVERTRAG' AND SCHLUESSEL='1234567' 4 GROUP BY TABELLE,SCHLUESSEL; EXPLAIN PLAN ausgeführt. SQL> select * from table(dbms_xplan.display); ----------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop | ----------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 43 | 78 | | | | 1 | SORT GROUP BY NOSORT | | 1 | 43 | 78 | | | | 2 | PARTITION RANGE ALL | | | | | 51 | 1 | | 3 | FIRST ROW | | 1 | 43 | 155 | | | | 4 | INDEX RANGE SCAN (MIN/MAX)| TBLSYNCHISTORY_IX2 | 1 | | 155 | 51 | 1 | ----------------------------------------------------------------------------------------------------- Ich denke der Unterschied ist klar oder? Auch hier sind die vom Optimizer geschätzten Zahlen korrekt. Darum ist es grausam einem Einsteiger direkt zu zeigen wie man es falsch mach. aber mit der abfrage ist es nicht möglich sich die spalte wert zurückgeben zu lassen. seh ich das richtig? Nimm die Spalte in das SELECT und die GROUP BY Klausel auf. Und verwende WHERE anstatt HAVING!! Dim Zitieren
newbii Geschrieben 31. Januar 2008 Autor Geschrieben 31. Januar 2008 Erstmals danke für die vielen Inputs! Der Ansatz von dbwizard hat mir schon mal weitergeholfen. Nur mit dem HAVING und WHERE klappt es noch nicht so. Wenn ich HAVING verwenden, dann klappt's, wenn ich WHERE nehmen, dann bekomme ich den Fehler: ORA-00933: SQL command not properly ended Meine Abfrage sieht so aus: SELECT max(DATUM) as myDate, WERT, LAND_ID, SPRACH_ID FROM TABELLE GROUP BY LAND_ID, SPRACH_ID, WERT WHERE (SRPACH_ID = '2') AND (LAND_ID = '22') ; Muss ich jeden Wert, den ich zusätzlich abfragen will in die GROUP BY nehmen? Ist das richtig? Danke nochmals für die tolle Unterstützung! Zitieren
dr.dimitri Geschrieben 31. Januar 2008 Geschrieben 31. Januar 2008 ORA-00933: SQL command not properly ended Zuerst kommt WHERE dann GROUP BY (und ggf. HAVING) dann ORDER BY. Siehe auch die Doku zum SELECT Muss ich jeden Wert, den ich zusätzlich abfragen will in die GROUP BY nehmen? Ist das richtig? Ja, sofern er nicht auch in einer Aggregatsfunktion verwendet wird. Also etwa in max,sum,agv etc. Dim Zitieren
newbii Geschrieben 31. Januar 2008 Autor Geschrieben 31. Januar 2008 Danke Dr. Dimitri! Ist ja schon peinlich meine Fehler... *tss*:upps Jetzt hab ich aber noch ein anderes Problem. Ich hab die Tabelle und Abfrage erweitert. Die Tabelle hat eine Spalte mehr bekommen. ID LAND_ID SPRACH_ID WERT DATUM KONTO 01 22 02 Wert1 01.01.2008 - 02 22 02 Wert2 02.01.2008 12345678 03 22 03 Wert3 01.01.2008 22155689 04 22 02 Wert4 03.01.2008 87654321 05 22 03 Wert5 05.01.2008 - Entsprechend hab ich die Abfrage erweitert: SELECT max(DATUM) as myDate, WERT, LAND_ID, SPRACH_ID, KONTO FROM TABELLE WHERE (SRPACH_ID = '2') AND (LAND_ID = '22') GROUP BY LAND_ID, SPRACH_ID, WERT, KONTO ; Da bei Konto aber unterschiedliche Werte sind, werden jetzt mehrere Resultate ausgegeben. Wie kann ich denn das jetzt wieder steuern, dass nur der neueste Eintrag ausgegeben wird? Danke! Zitieren
newbii Geschrieben 31. Januar 2008 Autor Geschrieben 31. Januar 2008 SELECT * FROM TABELLE WHERE (LAND_ID, SPRACH_ID, DATUM) IN (SELECT LAND_ID, SPRACH_ID, max(DATUM) FROM TABELLE WHERE (SPRACH_ID = '2') AND (LAND_ID = '22') GROUP BY LAND_ID, SPRACH_ID); Danke an alle die Ihren Input gegeben haben! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.