Announcement

Collapse
No announcement yet.

Selektion in Abh. des zuletzt gefundenen Datensatzes

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Selektion in Abh. des zuletzt gefundenen Datensatzes

    Hallo,

    ich möchte aus einer Tabelle Einträge in Abhängigkeit der bereits selektierten Daten wählen.

    Beispielhaft folgende Einträge in einer Tabelle:

    ID ;TIMESTMP
    1 ;13.02.2008 23:51:03
    2 ;13.02.2008 23:57:23
    3 ;13.02.2008 23:58:52
    4 ;14.02.2008 00:01:16
    5 ;14.02.2008 00:01:41
    6 ;14.02.2008 00:03:37
    7 ;14.02.2008 00:06:22
    8 ;14.02.2008 00:09:12
    9 ;14.02.2008 00:17:54
    10 ;14.02.2008 00:18:44

    Angenommen die Selektion erfolgt am 14.02.:
    Gesucht werden soll zunächst der erste Eintrag für den aktuellen Tag, also ID 4. Ausgehend davon soll geprüft werden, ob es Daten gibt, die einen Zeitstempel < dem Zeitstempel von ID 4 haben. Es sollen aber nur so lange Daten gewählt werden, bis die "Lücke" zw. zwei Zeitstempeln größer 5min ist (also ID 3 und 2). Gleiches soll für alle Datensätze mit einem Zeitstempel > dem Zeitstempel von ID 4 geschehen, ebenfalls bis die "Lücke" größer 5min wird (also 5, 6, 7, 8).

    Ergebnis für obiges Beispiel soll also sein:
    ID ;TIMESTMP
    2 ;13.02.2008 23:57:23
    3 ;13.02.2008 23:58:52
    4 ;14.02.2008 00:01:16
    5 ;14.02.2008 00:01:41
    6 ;14.02.2008 00:03:37
    7 ;14.02.2008 00:06:22
    8 ;14.02.2008 00:09:12

    Idealerweise sollte das Statement sowohl auf Oracle als auch auf DB2 laufen. Wer kann mir bei diesem Problem helfen?
    Danke!

  • #2
    Hallo firefighter,

    hier eine Lösung für Oracle - mit DB2 kenn ich mich nicht aus.

    Originally posted by firefighter View Post
    ...Angenommen die Selektion erfolgt am 14.02.:
    Gesucht werden soll zunächst der erste Eintrag für den aktuellen Tag, also ID 4. ...
    [highlight=sql]
    select min(ID) ID
    from tabelle
    where trunc(sysdate) = trunc(TIMESTMP)[/highlight]
    Originally posted by firefighter View Post
    ...Ausgehend davon soll geprüft werden, ob es Daten gibt, die einen Zeitstempel < dem Zeitstempel von ID 4 haben. Es sollen aber nur so lange Daten gewählt werden, bis die "Lücke" zw. zwei Zeitstempeln größer 5min ist (also ID 3 und 2). Gleiches soll für alle Datensätze mit einem Zeitstempel > dem Zeitstempel von ID 4 geschehen, ebenfalls bis die "Lücke" größer 5min wird (also 5, 6, 7, 8). ...
    [highlight=sql]
    select a.ID
    from tabelle a,
    (select i1.TIMESTMP
    from tabelle i1
    where i1.ID = (
    select min(i2.ID) ID
    from tabelle i2
    where trunc(sysdate) = trunc(i2.TIMESTMP)) b
    where a.TIMESTMP between b.TIMESTMP-(5/24/60) and b.TIMESTMP+(5/24/60)
    and a.TIMESTMP <> b.TIMESTMP[/highlight]

    Gruß Falk
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment


    • #3
      Hallo Falk,

      vielen Dank für Deine Antwort.
      Wahrscheinlich habe ich die Aufgabenstellung nicht exakt genug formuliert. Nachdem der erste Eintrag für den aktuellen Tag gefunden wurde, soll für aufsteigende Timestamps folgendes gemacht werden: Liegt der nächste Timestamp weniger als 5min vom Vorgänger entfernt wird der Datensatz selektiert (also 5, 6, 7 und 8 weil die Lücke zw. aufeinander folgenden Timestamps jeweils < 5min ist). Erst zw. 8 und 9 ist die Lücke größer 5min, sodass dieser Datensatz ignoriert wird. Mit einem einfachen SQL ist das sicherlich nicht zu lösen, eher mit einer Procedure. Hast Du ggf. eine Lösung oder einen Hinweis wie man sinnvollerweise an dieses Problem gehen sollte?

      Danke und Gruß,
      Firefighter

      Comment


      • #4
        Hallo,

        ich löse solche Probleme immer mit temporären Tabellen in einer StoredProcedure . Man könnte u.U. das auch in ein Statement packen, aber wenn man sich das nach einiger Zeit ansieht, dann braucht es wieder Zeit um den Inhalt zu verstehen. Also das prinzipielle Vorgehen ist folgendes:
        1. Ermittel die kleinste ID des gewünschten Tages (ID 4, hat Falk ja schon gezeigt). Das ist Deine SchlüsselID.
        2. Setze die Tabelle mit sich selbst in Beziehung über die ID zum nächsten/vorherigen Datensatz und berechne die Zeitdifferenz. (in #temptab)
        (Pseudocode)

        select a.ID, b.Timestamp - a.Tmestamp as Diff (bzw. a.Timestamp - b.Tmestamp as Diff)
        into #temptab1(bzw. 2)
        from tab a
        inner join tab b on b.ID = a.ID + 1 (bzw. ...= a.ID - 1)

        3. Nun ermittel die kleinste ID aus #temptab1 die größer ist als die SchlüsselID, und eine größere Differenz als die 5 Minuten hat. Das ist Deine MaxID.
        4. Nun ermittel die größte ID aus #temptab2 die kleiner ist als die SchlüsselID, und eine größere Differenz als die 5 Minuten hat. Das ist Deine MinID.
        5. Selektiere alle Datensätze Deiner Tabelle die ID >= MinID und ID <= MaxID besitzen.

        Ich bin sehr MSSQL-Server-lastig, daher nur der Pseudocode. Aber ich hoffe, dass ich Dir trotzdem etwas helfen konnte.

        Gruß
        Olaf

        Comment


        • #5
          Hallo,

          ich glaube nicht das sich dein Problem "sauber" mit Standard- SQL lösen läßt. Was ist in einer Datenmenge der Vorgänger bzw. Nachfolger eines Datensatzes? Dies ist immer von der Sortierung abhängig. Auch deine Felder lassen keine Logik zu, die zwingend auf den Vorgänger/Nachfolger schließen läßt. Die Lösung von Olaf über ID-1/ID+1 ist nur eine "Krücke" (Sorry Olaf ) und setzt zwingend voraus, das die IDs fortlaufend und ohne Lücken sind. Allerdings ist der Ansatz ausbaufähig man kann da sicherlich was zusammenbauen. Die Stichworte dazu sind automatisch erzeugte Zeilennummern und Views. Das wird dann aber sehr stark abhängig vom verwendeten DBMS.

          Gruß Falk
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment

          Working...
          X