Holger: das zweit-, dritt-, viert-aktuellste Datum aus DB holen

Hallo zusammen,

ich sitze schon seit gestern an folgendem Problem:
Ich muss bestimmt Log-Infos mit Perl aus einer Oracle DB holen, zunächst interessiert die Log-Info mit dem aktuellsten Datum im record_insert_ts:

--------------schnipp------------
 SELECT log_info, record_insert_ts
 FROM table2
 WHERE TO_CHAR(record_insert_ts, 'DD.MM.YYYY') =
 TO_CHAR((SELECT MAX(record_insert_ts) FROM table2), 'DD.MM.YYYY')
--------------schnapp------------

Mit diesem SQL-Befehl bekomme ich den Datensatz aus der Oracle DB, der das aktuellste Datum im record_insert_ts enthält.
Wie kann ich nun das zweit- dritt und viertaktuellste erhalten?
Ich möchte eine Art Navigation erstellen, die es erlaubt, auf Wunsch die Log-Info des nächstfrüheren und nächstspäteren Datums zu sehen.

Im Forum hab ich nachgelesen, dass es in MYSQL einen Befehl namens Limit gibt, mit dem soetwas möglich wäre. Für Oracle hab ich da jedoch noch nichts vergleichbares gefunden.

Besten Dank im voraus,
Holger

  1. Hi,

    Wie kann ich nun das zweit- dritt und viertaktuellste erhalten?

    Dein Statement schränkt das Resultset auf exakt einen Datensatz ein, so kommst Du also gar nicht weiter. Sortiere nach dem Aktualitätskriterium, und hole die ersten n benötigten Zeilen heraus. Beschäftige Dich dazu auch mit der Pseudospalte rownum.

    Im Forum hab ich nachgelesen, dass es in MYSQL einen Befehl namens Limit gibt, mit dem soetwas möglich wäre. Für Oracle hab ich da jedoch noch nichts vergleichbares gefunden.

    Oracle kennt neben rownum nichts vergleichbares. Glücklicherweise kann man mit Subselects sehr viel gewinnen.

    Cheatah

    --
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Dein Statement schränkt das Resultset auf exakt einen Datensatz ein, so kommst Du also gar nicht weiter. Sortiere nach dem Aktualitätskriterium, und hole die ersten n benötigten Zeilen heraus. Beschäftige Dich dazu auch mit der Pseudospalte rownum.

      Hi Cheatah,

      das stimmt, so erhalte ich nur einen Datensatz.
      Meine Tabelle ist so aufgebaut:

      LOG_INFO:                   RECORD_INSERT_TS
      -------------------------|-------------------
      START BLC Oracle refresh |  19.05.2003
      Start_Loading_HDD_Cube   |  19.05.2003
      START Loading BLC Cube   |  19.05.2003
      Load BLC Cube Failed     |  19.05.2003
      END BLC Oracle refresh   |  19.05.2003
      Start_Loading_UNV_Cube
      (...)

      Das Problem ist, dass es schwieriger wird, wenn ich mir mehrere Datensätze für die ersten drei aktuellsten RECORD_INSERT_TS herausholen lasse, da die infos für ein Datum nicht in einer Zeile in Form von Tabellenspalten, sondern in mehreren Zeilen stehen.

      In meinem Fall gilt also: Ein Datensatz != Eine Reihe des Recordsets.

      Ist es nicht möglich, ein Statement der Form für das zweitaktuellste Datum zu machen?

      ------------schnipp-----------
      SELECT log_info, record_insert_ts
       FROM table2
       WHERE TO_CHAR(record_insert_ts, 'DD.MM.YYYY') =
       TO_CHAR((SELECT MAX(record_insert_ts) AS tempvar FROM
       table2), 'DD.MM.YYYY')
       AND record_insert_ts < tempvar
      ------------schnapp-----------
      ich weiss, dass sich beide Bedingung widersprechen, aber vielleicht führt dieser Anfang doch zu einer Lösung...

      1. Hi Holger,

        Das Problem ist, dass es schwieriger wird, wenn ich mir mehrere Datensätze für die ersten drei aktuellsten RECORD_INSERT_TS herausholen lasse, da die infos für ein Datum nicht in einer Zeile in Form von Tabellenspalten, sondern in mehreren Zeilen stehen.

        Du brauchst also eine Menge von (implizit beschriebenen) Mengen?

        Dann wirst Du Deine Datenerfassungslogik möglicherweise in Form entsprechender Schleifen auf 3GL-Ebene formulieren müssen, statt mit einem einzigen SQL-Statement. Was die Performance angeht, solltest Du allerdings Host-Variablen nutzen können, um den SQL-Parsing-Aufwand zu minimieren.

        Alternative (aufgrund der Endlichkeit der "4" in Deiner Aufgabenstellung):
        1. SQL-Statement: Berechne die 4 Elemente
        2. SQL-Statement: Verwende diese in einem "IN"-Ausdruck der WHERE-Klausel.
           (Der Performanz wird durch Deine Indexstrukturen Rechnung getragen.)

        Ganz andere Idee: Brauchst Du wirklich eine Menge von Einträgen, die ausschließlich durch  ihre _Anzahl_ beschrieben sind?
        Überlege Dir, ob Dein Problem nicht durch einen völlig anderen Ansatz, etwa Datums-Arithmetik, eleganter zu lösen wäre.

        Viele Grüße
              Michael

        --
        T'Pol: I apologize if I acted inappropriately.
        V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
        (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
         => http://www.peter.in-berlin.de/projekte/selfcode/?code=sh%3A|+fo%3A}+ch%3A]+rl%3A(+br%3A^+n4%3A(+ie%3A%25+mo%3A)+va%3A|+de%3A%2F+zu%3A|+fl%3A(+ss%3A)+ls%3A~+js%3A|
        Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.
  2. Hallo,

    Du benutzt das veraltete Datumsformat DD.MM.YYYY. Nimm lieber YYYY-MM-DD, also etwa 2003-07-31

    Das ist nämlich Standard nach DIN 5008. Steht auch jetzt so im Duden. Das alte Format soll damit ersetzt werden, um die nationalen Formate an das internationale Format ISO 8601 anzupassen.

    Gerade wenn man etwas programmiert tut man seinen Nachfolgern und sich einen großen Gefallen, wenn man in zwei Jahren nicht wieder alles auf den dann nur noch verwendeten Standard bringen muss.

    Den alten Standard sollte man daher möglichst gar nicht mehr verwenden.

    Linktipp: Regeln für die Textverarbeitung (pdf), Duden, Seite 5! http://www.duden.de/service/download/textverarbeitung_duden1.pdf

    Grüße
    Heiner

    1. Hi Heiner,

      Du benutzt das veraltete Datumsformat DD.MM.YYYY. Nimm lieber YYYY-MM-DD, also etwa 2003-07-31
      Das ist nämlich Standard nach DIN 5008. Steht auch jetzt so im Duden. Das alte Format soll damit ersetzt werden, um die nationalen Formate an das internationale Format ISO 8601 anzupassen.

      gerade im Kontext der laufenden Diskussion: DIN 5008 erlaubt zwar String-Vergleichbarkeit, nicht aber einfache arithmetische Operationen.

      Falls die Aufgabe also sinngemäß "nicht älter als vier Werktage" lauten sollte, könnte man dies durch eine gezielt darauf abgestimmte Änderung des Datums-Format (nämlich eine, die einem UNIX time stamp entspricht) noch wesentlich besser unterstützt werden. (Obwohl auch String-Sortierbarkeit in dieser Hinsicht schon helfen würde, weil man die Datums-Arithmetik dann eben erledigt, während der SQL-Code generiert wird.)
      Die Visualisierung gegenüber den Benutzern steht dann ja noch mal auf einem anderen Blatt ...

      Viele Grüße
            Michael

      --
      T'Pol: I apologize if I acted inappropriately.
      V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
      (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
       => http://www.peter.in-berlin.de/projekte/selfcode/?code=sh%3A|+fo%3A}+ch%3A]+rl%3A(+br%3A^+n4%3A(+ie%3A%25+mo%3A)+va%3A|+de%3A%2F+zu%3A|+fl%3A(+ss%3A)+ls%3A~+js%3A|
      Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.
      1. Die Visualisierung gegenüber den Benutzern steht dann ja noch mal auf einem anderen Blatt ...

        Ich denke, dass die meisten Bundesbürger inzwischen an das neue Format gewöhnt sein dürften. Auf jeden Fall gilt das für Internetnutzer. Die werden damit ja quasi jeden Tag konfrontiert.

        Heiner

        1. Hi Heiner,

          Die Visualisierung gegenüber den Benutzern steht dann ja noch mal auf einem anderen Blatt ...
          Ich denke, dass die meisten Bundesbürger inzwischen an das neue Format gewöhnt sein dürften.

          darum ging es mir nicht. Ich fürchte, daß Dein Vorschlag "zu kurz gesprungen" sein könnte - und wenn schon das kostbare Datenmodell inkompatibel "anfassen", dann lieber gleich richtig.

          Viele Grüße
                Michael

          --
          T'Pol: I apologize if I acted inappropriately.
          V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
          (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
           => http://www.peter.in-berlin.de/projekte/selfcode/?code=sh%3A|+fo%3A}+ch%3A]+rl%3A(+br%3A^+n4%3A(+ie%3A%25+mo%3A)+va%3A|+de%3A%2F+zu%3A|+fl%3A(+ss%3A)+ls%3A~+js%3A|
          Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.