Eine kleine, harte Nuss

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Eine kleine, harte Nuss

    Hallo zusammen,

    mit diesem query...

    Code:
    SELECT id, article_id, tstamp
    FROM contribution
    ORDER BY article_id, tstamp;
    ...erzeuge ich diese tabelle...



    ...jetzt möchte ich ein alternatives query schreiben, welches mir immer "nur" die ROT MARKIERTEN zeilen liefert (also immer die "erste" zeile einer article_id). Ich sitze schon seit langer Zeit da dran und komme einfach nicht auf eine korrekte und performante Lösung. Meine "beste Version" (die aber nicht läuft habe ich mittels eines modifizierten LIMIT gemacht).

    Wäre GENIAL, wenn mir jemand einen Tritt/Tipp geben könnte! ;-)

    Danke und Grüße,
    Chris

  • #2
    Hallo,

    Code:
    select c1.id, c1.article_id, c1.tstamp
    from contribution as c1
    left join contribution as c2 on c2.article_id = c1.article_id and c2.tstamp < c1.tstamp
    where c2.id is null
    order by article_id
    Gruß,

    Amica
    Zuletzt geändert von AmicaNoctis; 08.03.2010, 00:43. Grund: Tippfehler im SQL korrigiert
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Hey Amica,

      vielen Dank!! Aber kann es sein, dass man aus dem "c1.id" in der WHERE-clause ein "c2.id" machen muss? (denn sonst ist das result set leer)

      Code:
      SELECT c1.id, c1.article_id, c1.tstamp
      FROM contribution AS c1
      LEFT JOIN contribution AS c2 ON c2.article_id = c1.article_id AND c2.tstamp < c1.tstamp
      WHERE c2.id IS NULL
      ORDER BY article_id
      Danke und LG,
      Chris

      Kommentar


      • #4
        Zitat von squirrelcgn Beitrag anzeigen
        kann es sein, dass man aus dem "c1.id" in der WHERE-clause ein "c2.id" machen muss?
        Richtig erkannt, war nur ein Tippfehler.
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          Uaaaaaaa, irgendetwas liegt aber noch heftigst im argen:

          - Es gibt insgesamt 20170 articles (article_id).
          - Nach dem "LEFT JOIN" query habe ich aber 20242 zeilen....... :-(

          Direkt gefragt: gibt es noch eine Lösung OHNE LEFT JOIN? (und ohne jegliche JOINs)

          Danke und Grüße,
          Chris

          Kommentar


          • #6
            Kann es sein, dass du da 72 contributions ohne article ID hast? Such mal nach NULL-Werten in dieser Spalte.

            Edit: Es gäbe eine Lösung ohne Joins, aber das wäre dann eine korrelierte Unterabfrage und die ist höchst unperformant. Dieser negative self left join ist da schon die sinnvollste Lösung. Wenn dir allerdings die contribution ID egal wäre, könntest du auch mit group by und min(tstamp) arbeiten.
            Zuletzt geändert von AmicaNoctis; 08.03.2010, 01:12.
            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
            Super, danke!
            [/COLOR]

            Kommentar


            • #7
              Leider nein! ;-) (mein DB-modell verbietet dies bereits...) Danke trotzdem.

              Werde morgen weitergrübeln.

              Kommentar


              • #8
                Dann sind es die tstamp-Werte, die unerwarteter Weise null sind. In diesem Falle hättest du aber ohnehin spezifizieren müssen, ob solche tstamps als die kleinsten oder die größten betrachtet werden sollen, wenn man danach sortiert.
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Kommentar


                • #9
                  Hier noch ein alternativer SQL, wobei ich den nur der Vollständigkeit wegen hier aufnehme, die Variante von Amica sollte eigentlich performanter sein.

                  Code:
                  SELECT
                    `contribution`.*
                  FROM
                    `contribution`
                    LEFT JOIN (
                      SELECT
                        `contribution`.`article_id`  AS `aid`,
                        MAX(`contribution`.`tstamp`) AS `newest`
                      FROM
                        `contribution`
                      GROUP BY
                        `contribution`.`article_id`
                    ) AS `contribution_check` ON (
                      `contribution_check`.`aid` = `contribution`.`article_id`
                    )
                  WHERE
                    `contribution`.`tstamp` = `contribution_check`.`newest`
                  Erklärung: Das ist jetzt mit einer Subquery die über LEFT JOIN reingeholt wird und positiv prüft. Das ganze allerdings im FROM-Teil damit er die Subquery nicht für jeden Datensatz ausführt...
                  Zuletzt geändert von DSitC; 08.03.2010, 16:00. Grund: Die Tabelle heißt ja "contribution" und nicht "foo"... -.-

                  Kommentar


                  • #10
                    Hallo zusammen,

                    erst einmal vielen, herzlichen Dank für eure hervorragenden Beiträge!

                    @Amica: "leider" hat nur ein einziger tstamp den Wert 0000-00-00 00:00:00
                    @DSitC: danke, wieder was gelernt

                    Wie sehr ich die Daten auch "reinige" und Prüfsummen bilde und damit Checks durchführe, ich habe irgendwo einen SEMANTISCHEN Fehler in meinen Daten. Die Tabelle contribution ist nur eine von vielen, die ich während eines Workflows erzeuge.

                    Fange jetzt nochmal von vorne an und werde NOCH sorgfältiger vorgehen, als ich es ohnehin schon immer tue! ;-)

                    LG und nochmals danke,
                    Chris

                    Kommentar


                    • #11
                      Hallo zusammen,

                      wie ihr seht, lässt mich das Problem nicht mehr los! ;-) Habe jetzt alles nochmal neu aufgebaut und sehe nun, wo das Problem liegt! :-)

                      Jetzt würde es direkt zur Lösung führen, wenn mir jemand folgende Frage beantworten könnte:

                      Wie kann ich das von Amica erarbeitete Query so modifizieren, dass ich nicht nur nach 1 Spalte "suche"/"gruppiere", sondern nach 2 Spalten: also article_id UND group_id?
                      Hintergrund: die gleiche article ID kommt in verschiedenen groups vor, ABER das "ignoriere" ich natürlich, wenn ich die group ID nicht berücksichtige... (peinlich)

                      Hier nochmal das Query:
                      Code:
                      SELECT c1.id, c1.article_id, c1.tstamp
                      FROM contribution AS c1
                      LEFT JOIN contribution AS c2 ON c2.article_id = c1.article_id AND c2.tstamp < c1.tstamp
                      WHERE c2.id IS NULL
                      ORDER BY article_id;
                      Vielen Dank und viele Grüße,
                      Chris

                      Kommentar


                      • #12
                        Das müsste dann so aussehen, denke ich mal...

                        Code:
                        SELECT
                          c1.id,
                          c1.group_id,
                          c1.article_id,
                          c1.tstamp
                        FROM
                          contribution AS c1
                          LEFT JOIN contribution AS c2 ON (
                            c2.group_id = c1.group_id AND
                            c2.article_id = c1.article_id AND
                            c2.tstamp < c1.tstamp
                          )
                        WHERE
                          c2.id IS NULL
                        ORDER BY
                          article_id;

                        Kommentar


                        • #13
                          Vielen Dank, DSitC!!

                          Das genau löst es (hätte ich auch gut mal selbst drauf kommen können - war wohl etwas spät gestern...).

                          LG,
                          Chris

                          Kommentar


                          • #14
                            Zitat von squirrelcgn Beitrag anzeigen
                            Vielen Dank, DSitC!!

                            Das genau löst es (hätte ich auch gut mal selbst drauf kommen können - war wohl etwas spät gestern...).

                            LG,
                            Chris
                            Naja, das SQL stammt ja von Amica, ich hab nur eine Zeile eigefügt... ;-)

                            Kommentar


                            • #15
                              Okay, ich habe natürlich auch Amicas Beitrag positiv bewertet (mit dem Bewertungstool)... aber das DANKE von vorhin gilt natürlich auch euch BEIDEN!

                              @ Amica und DSitC

                              ;-)

                              Kommentar

                              Lädt...
                              X