Announcement

Collapse
No announcement yet.

Zeilen in Tabelle vergleichen

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

  • Zeilen in Tabelle vergleichen

    Guten Abend Zusammen !

    Ich bin ein relativer SQL Neuling und arbeite mit MS SQL 2005 und Delphi.
    Meine Suche im Forum hat nichts ergeben, da ich auch nicht so ganz sicher weiss, welche Suchbegriffe mich bei folgendem Problem weiterbringen:

    Ich werte innerhalb einer Datenbank 2 Tabellen mit Zeitstempeln und zugeordneter Produktnummer mit folgendem Ergebnis aus:

    Zeitstempel ProduktNr Produktbezeichnung
    2008-09-19 08:05:14.000 14 AAAAAAA
    2008-09-19 08:05:16.000 14 AAAAAAA
    ...
    2008-09-19 12:43:48.000 14 AAAAAAA
    2008-09-19 12:44:07.000 14 AAAAAAA
    2008-09-19 13:46:44.000 17 BBBBBB
    2008-09-19 13:46:45.000 17 BBBBBB
    ....
    2008-09-19 18:55:21.000 17 BBBBBB
    2008-09-19 18:55:32.000 17 BBBBBB
    2008-09-19 18:56:14.000 18 CCCCC
    2008-09-19 18:57:05.000 18 CCCCC
    ....
    2008-09-19 19:26:17.000 18 CCCCC
    2008-09-19 19:36:24.000 18 CCCCC
    2008-09-20 08:54:47.000 14 AAAAAAA
    2008-09-20 09:02:48.000 14 AAAAAAA

    Ich würde die Abfrage gerne so gestalten, dass jeweils nur die Sätze mit "neuer" ProduktNr ausgegeben werden,also ungefähr so:

    Zeitstempel ProduktNr Produktbezeichnung
    2008-09-19 08:05:14.000 14 AAAAAAA
    2008-09-19 13:46:44.000 17 BBBBBB
    2008-09-19 18:56:14.000 18 CCCCC
    2008-09-20 08:54:47.000 14 AAAAAAA

    Ich habe schon eine Abfrage mit MIN und MAX im GROUP BY probiert, das hat den Nachteil, dass eine mehrfach auftretende ProduktNr (hierz.B. 14) nur einmal ausgegeben wird:

    SELECT MIN(Zeit) as Start, MAX(Zeit) as Ende, Nr as ProduktNummer
    FROM Ereignis INNER JOIN
    Wert ON Ereignis.ID = Wert.Ereignis_ID
    AND Ereignis.Zeit BETWEEN '11.09.2008 08:00:00' AND '15.09.2008 16:00:00'
    INNER JOIN
    Products ON Wert.Nr = Products.Nummer

    GROUP BY Nr
    ORDER BY Start

    Die Lösung in Delphi ist so umgesetzt, dass ich mir die komplette Abfrage ausgeben lasse und jeweils Zeile n und n+1 auf Änderung vergleiche. Das ist jedoch aufwendig und braucht eine menge Ressourcen.

    Hat jemand eine Idee, wie das Problem elegant in SQL gelöst werden kann ?

    Grüsse

    Tom

  • #2
    Ich habe schon eine Abfrage mit MIN und MAX im GROUP BY probiert, das hat den Nachteil, dass eine mehrfach auftretende ProduktNr (hierz.B. 14) nur einmal ausgegeben wird:
    Also hier widersprichst Du aber deinem geposteten Ergebnis, aber egal. Wenn Du einfach das MIN wegläßt, dann hast Du dein gewünschtes Ergebnis.

    Dim
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #3
      Hallo Dim,

      erstmal Danke für Deine Antwort, die ich jedoch nicht ganz verstehe.
      Das SQL-Script:

      SELECT MIN(Zeit) as Start, MAX(Zeit) as Ende, Nr as ProduktNummer
      FROM Ereignis INNER JOIN
      Wert ON Ereignis.ID = Wert.Ereignis_ID
      AND Ereignis.Zeit BETWEEN '11.09.2008 08:00:00' AND '15.09.2008 16:00:00'
      INNER JOIN
      Products ON Wert.Nr = Products.Nummer

      GROUP BY Nr
      ORDER BY Start

      hat meiner Meinung (und den Tests) nach das Problem, dass die Produktnummern nicht mehrfach auftauchen, sondern nur einmal, wobei MAX(Zeit) immer die Zeit des letzten Auftauchens ist.

      Mein Wunschergebnis ist:

      Zeitstempel ProduktNr Produktbezeichnung
      2008-09-19 08:05:14.000 14 AAAAAAA
      2008-09-19 13:46:44.000 17 BBBBBB
      2008-09-19 18:56:14.000 18 CCCCC
      2008-09-20 08:54:47.000 14 AAAAAAA

      tatsächlich kommt aber:

      Zeitstempel ProduktNr Produktbezeichnung
      2008-09-20 08:54:47.000 14 AAAAAAA (hier steht dann das Maximum)
      2008-09-19 13:46:44.000 17 BBBBBB
      2008-09-19 18:56:14.000 18 CCCCC

      da ja der letzte Zeitstempel das Maximum für Produktnummer 14 darstellt.
      Du hast natürlich Recht, das Script gibt auch das Minimum aus, was aber nicht das Problem ist.

      Oder liege ich jetzt total falsch ?

      Tom

      Comment


      • #4
        Hallo Tom M,
        Originally posted by Tom M View Post
        ...das Problem, dass die Produktnummern nicht mehrfach auftauchen, sondern nur einmal, wobei MAX(Zeit) immer die Zeit des letzten Auftauchens ist.
        Das entspricht aber genau deiner Ausgangsbedingung:

        Originally posted by Tom M View Post
        ...Ich würde die Abfrage gerne so gestalten, dass jeweils nur die Sätze mit "neuer" ProduktNr ausgegeben werden...
        Du müßtest also zuerst mal eindeutig definieren was eine "neue" Produktnummer ist. Rein Datentechnisch kann man dein "Wunschergebnis" nämlich nicht nachvollziehen. SQL arbeitet immer Mengenorientiert - die physische Reihenfolge von Datensätzen spielt keine Rolle.

        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


        • #5
          Hallo Zusammen,

          Danke für Eure Antworten, die mir helfen die Gedanken zu sortieren.
          Ich probiers mal:

          Es liegt eine Tabelle vor, in der Ereignisse mitgeschrieben und mit Zeitstempel versehen werden. Eines dieser "Ereignisse" ist die Produktnummer.
          Die Produktnummer 1 wird zu einem Zeitpunkt X angelegt und jedes weitere Ereignis, das einen Zeitstempel bekommt, trägt auch diese Produktnummer.
          Zu einem Zeitpunkt Y wird dann eine andere Produktnummer 2 angelegt, zu einem weiteren Zeitpunkt Z die nächste usw.

          Das Ziel ist jetzt, auf dem fortlaufenden Zeitstrahl (basierend auf den Zeitstempeln) diejenigen Zeitstempel Y und Z zu finden, an denen die Produktnummer wechselt.

          Zusätzliche Bedingung ist, dass bereits verwendete Produktnummern immer wieder auftauchen dürfen, d.h. zum Zeitpunkt X ProduktNr 1, Y ProduktNr 2 und Z wieder ProduktNr 1.

          Ich hoffe, dass diese sortierten Gedanken weiterhelfen !

          Grüsse

          Tom

          Comment


          • #6
            Hallo Tom,

            wie ich schon sagte arbeitet SQL Mengenorientiert und unabhängig von der "Reihenfolge" der Datensätze. Solange du die Datensätze die zu einem "Ereignis" gehören nicht eindeutiger spezifizieren kannst, als das keine Ereignisse mit anderer Produktnummer "dazwischen" liegen dürfen, solange läßt sich dies mit reinem SQL nicht lösen. Du wirst also darauf angewiesen bleiben, die Anzeige entweder in der Anwendung aufzubereiten, oder das ganze in eine SP zu verlagern und die Logik dort zu implementieren.

            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


            • #7
              Hallo,

              Danke für Eure Antworten, die mir geholfen haben, die Gedanken zu strukturieren und die Lösung selbst zu finden.
              Ich habe das Thema mit einer Subquery gelöst, da glücklicherweise in der Tabelle nicht nur ein Zeitstempel je Datensatz abgelegt ist, sondern auch eine ID.

              SELECT E.Zeit as Ende, SS.Wert as ProduktNummer, P.ProductName as ProduktBezeichnung

              FROM Ereignis as E INNER JOIN
              Werte as SS ON E.ID = SS.Ereignis_ID
              AND E.Zeit BETWEEN '11.09.2008 08:00:00' AND '15.10.2008 16:00:00'
              INNER JOIN
              Products as P ON SS.Wert = P.Nummer

              WHERE Wert <>
              ( SELECT S.Wert as ProduktNummer
              FROM Werte as S
              WHERE S.Ereignis_ID = SS.Ereignis_ID + 1)

              ORDER BY Zeit
              In der äusseren Abfrage wird eine Produktnummer mit der zugehörigen ID ausgegeben und mit der Abfrage der ID+1 in der inneren Abfrage verglichen.

              Grüsse

              Tom

              Comment

              Working...
              X