Announcement

Collapse
No announcement yet.

Distinct + Join

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

  • Distinct + Join

    Hallo zusammen,

    ich habe ein Performance Problem mit einer Abfrage. Es handelt sich dabei um eine Produktionsdatenbank. Als Ergebnis möchte ich diverse Mittelwerte und Summen, gruppiert nach Maschineninventarnummer, erhalten.

    Nun, aus der Produktion kam die Anfrage, ob es nicht auch möglich wäre die Maschinen, welche an diesen Tagen nichts produziert haben anzuzeigen. Gelöst habe ich das nun wiefolgt:

    Code:
    SELECT DISTINCT Maschine, Avg1, Avg2, Sum1 FROM Tabelle1 t
    LEFT JOIN (SELECT Maschine, 'Avg1'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf1 ON t.Maschine = abf1.Maschine
    LEFT JOIN (SELECT Maschine, 'Avg2'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf2 ON t.Maschine = abf2.Maschine
    LEFT JOIN (SELECT Maschine, 'Sum'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf3 ON t.Maschine = abf3.Maschine
    WHERE Maschine IN ('..','..',...,'..')
    Das Problem dabei ist, dass die Tabelle1 unheimlich viele Datensätze enthält und DISTINCT Abfrage extrem lang dauert. Diese ist jedoch eigentlich total unnötig, da ich genau die Maschinen die ich in der WHERE Klausel angebe als Ergebnis wieder haben möchte. Nun habe ich schon bspw. mit SELECT 'Maschine' IN (...) versucht, aber mehr als 'Maschine' = ... funktioniert leider nicht.

    Hat jemand von euch eine Idee, wie ich ohne die Datenbank darauf abzufragen die (vorgegebenen) Maschinennummern ausgegeben bekomme?

    Danke schonmal im Voraus.

  • #2
    Originally posted by madoc View Post
    Code:
    SELECT DISTINCT Maschine, Avg1, Avg2, Sum1 FROM Tabelle1 t
    LEFT JOIN (SELECT Maschine, 'Avg1'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf1 ON t.Maschine = abf1.Maschine
    LEFT JOIN (SELECT Maschine, 'Avg2'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf2 ON t.Maschine = abf2.Maschine
    LEFT JOIN (SELECT Maschine, 'Sum'=... FROM Tabelle1 WHERE DATUM = '...' AND Maschine IN ('..','..',...,'..') GROUP BY Maschine) abf3 ON t.Maschine = abf3.Maschine
    WHERE Maschine IN ('..','..',...,'..')
    Wozu die Joinerei?

    [HIGHLIGHT="SQL"]
    SELECT Maschine, Avg (Avg1), Avg(Avg2), Sum (Sum1)
    FROM Tabelle1 t
    WHERE Maschine IN ('..','..',...,'..')
    GROUP BY Maschine[/HIGHLIGHT]

    Comment


    • #3
      Originally posted by ebis View Post
      Wozu die Joinerei?

      [HIGHLIGHT="SQL"]
      SELECT Maschine, Avg (Avg1), Avg(Avg2), Sum (Sum1)
      FROM Tabelle1 t
      WHERE Maschine IN ('..','..',...,'..')
      GROUP BY Maschine[/HIGHLIGHT]

      weil ich die Mittelwerte nur von einem Tag haben möchte und nicht über alle Daten die in der Tabelle zu der jeweiligen Maschine stehen?

      Comment


      • #4
        Originally posted by madoc View Post
        weil ich die Mittelwerte nur von einem Tag haben möchte und nicht über alle Daten die in der Tabelle zu der jeweiligen Maschine stehen?
        Dann pack den Tag doch ins Select...

        Comment


        • #5
          Originally posted by ebis View Post
          Dann pack den Tag doch ins Select...
          Entschuldige - wie das?

          Comment


          • #6
            Originally posted by madoc View Post
            Entschuldige - wie das?
            [HIGHLIGHT="SQL"]SELECT Maschine, Datum, Avg (Avg1), Avg(Avg2), Sum (Sum1)
            FROM Tabelle1 t
            WHERE Maschine IN ('..','..',...,'..')
            GROUP BY Maschine, Datum[/HIGHLIGHT]oder
            [HIGHLIGHT="SQL"]SELECT Maschine, Avg (Avg1), Avg(Avg2), Sum (Sum1)
            FROM Tabelle1 t
            WHERE Maschine IN ('..','..',...,'..')
            AND Datum = '...'
            GROUP BY Maschine[/HIGHLIGHT]

            Comment


            • #7
              Originally posted by ebis View Post
              [HIGHLIGHT="SQL"]SELECT Maschine, Datum, Avg (Avg1), Avg(Avg2), Sum (Sum1)
              FROM Tabelle1 t
              WHERE Maschine IN ('..','..',...,'..')
              GROUP BY Maschine, Datum[/HIGHLIGHT]oder
              [HIGHLIGHT="SQL"]SELECT Maschine, Avg (Avg1), Avg(Avg2), Sum (Sum1)
              FROM Tabelle1 t
              WHERE Maschine IN ('..','..',...,'..')
              AND Datum = '...'
              GROUP BY Maschine[/HIGHLIGHT]
              Nun - ich würde die Performance meiner Abfrage gerne erhöhen, nicht noch weiter vermiesen. Den Mittelwert über alle Daten gruppiert nach Maschinen und Datumswerten zu bilden, nur um den Mittelwert für einen einzigen Tag (that's all I want ...) zu bekommen ist doch etwas übertrieben ...

              Letztere Abfrage gibt mir hingegen wieder nur die Maschinen aus, welche an diesem Tag auch produziert haben. Maschinen welche an diesem Tag nichts produziert haben werden nicht ausgegeben...

              Hast du das eigentliche Problem nun verstanden?

              Comment


              • #8
                Hast du das eigentliche Problem nun verstanden?
                Wir haben's aber Du hast noch Probleme beim Verstehen der Lösung. Mit der WHERE Klausel wird die Treffermenge eingeschränkt auf die gewünschten Maschinen und das Datum. Dann erst wird die Gruppierung durchgeführt.

                In deinem ursprünglichen SQL wird keine Einschränkung hinsichtlich des Datums vorgenommen, d.h. Du bekommst das Ergebniss aller Einträge (mit ein paar Outer Join Roundtrips die absolut unnötig sind).

                Leg einen zusammengesetzten Index auf Maschinen und Datum, ändere die Abfrage und los gehts.

                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


                • #9
                  Originally posted by madoc View Post
                  Letztere Abfrage gibt mir hingegen wieder nur die Maschinen aus, welche an diesem Tag auch produziert haben. Maschinen welche an diesem Tag nichts produziert haben werden nicht ausgegeben...
                  Waurm outer joints du das dann nicht gegen die Tabelle, die die Maschinen enthält?

                  Comment


                  • #10
                    Originally posted by dimitri View Post
                    Wir haben's aber Du hast noch Probleme beim Verstehen der Lösung. Mit der WHERE Klausel wird die Treffermenge eingeschränkt auf die gewünschten Maschinen und das Datum. Dann erst wird die Gruppierung durchgeführt.

                    In deinem ursprünglichen SQL wird keine Einschränkung hinsichtlich des Datums vorgenommen, d.h. Du bekommst das Ergebniss aller Einträge (mit ein paar Outer Join Roundtrips die absolut unnötig sind).

                    Leg einen zusammengesetzten Index auf Maschinen und Datum, ändere die Abfrage und los gehts.

                    Dim
                    Falsch - ich habe bewusst keine Einschränkung des Datums, damit ich jeden "Maschinen"-Wert bekomme. Es produzieren nunmal nicht alle Maschinen jeden Tag, d.h. wenn ich das Datum allgemein als WHERE Klausel verwende, so fallen die Maschinen die an diesem Tag nicht produziert haben raus, sprich ich bekomme diese beim Ergebnis nicht angezeigt.
                    Hingegen habe ich durchaus eine Datumseinschränkung da wo ich sie brauche, nämlich bei der Berechnung der Mittelwerte/Summen.

                    Mit dem was du vorschlägst bekomme ich nicht das Ergebnis, welches ich mir von der Abfrage erwarte. Keine Ahnung ob das nun so schwer zu verstehen ist oder ob ich es so schlecht beschreiben kann ...

                    Comment


                    • #11
                      Originally posted by madoc View Post
                      Falsch - ich habe bewusst keine Einschränkung des Datums, damit ich jeden "Maschinen"-Wert bekomme. Es produzieren nunmal nicht alle Maschinen jeden Tag, d.h. wenn ich das Datum allgemein als WHERE Klausel verwende, so fallen die Maschinen die an diesem Tag nicht produziert haben raus, sprich ich bekomme diese beim Ergebnis nicht angezeigt.
                      Hingegen habe ich durchaus eine Datumseinschränkung da wo ich sie brauche, nämlich bei der Berechnung der Mittelwerte/Summen.

                      Mit dem was du vorschlägst bekomme ich nicht das Ergebnis, welches ich mir von der Abfrage erwarte. Keine Ahnung ob das nun so schwer zu verstehen ist oder ob ich es so schlecht beschreiben kann ...
                      Poste doch Deine Tabelle(n) samt mit ein paar Datensätzen gefüllt sowie dem Ergegnis das Du Dir erhoffst anstatt einer Beschreibung....

                      Comment

                      Working...
                      X