Jeweils mit erster Zeile updaten

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

  • Jeweils mit erster Zeile updaten

    Ich möchte folgendes Problem mit einer SQL Abfrage lösen, komme aber aktuell noch nicht weiter.

    Vereinfachte Tabellen:

    Tabelle1
    ------------
    t1_id
    user
    warteschlange
    anzahl

    Tabelle2
    -----------
    t2_id
    user
    platz_1
    platz_2
    aktuell_1
    aktuell_2



    Ich habe die 2 obigen Tabellen. Eine Tabelle enthält eine Warteschlange. Bzw.
    genauer mehrere Warteschlangen. Jeder Eintrag in der Warteschlange enthält eine Spalte in der steht wofür er wartet (Hier nur 1 und 2), welchem Benutzer er gehört und eine Anzahl.

    In die zweite Tabelle rutschen dann nach und nach Informationen aus der Warteliste.

    Dazu soll in dem Query folgendes passieren:

    Zuerst werden alle Einträge aus Tabelle2 gesucht, bei denen aktuell_1 = 0 ist. Dazu passend soll der Eintrag mit der kleinsten Id aus Tabelle1 gesucht werden, der dem selben benutzer gehört und in der Warteschlange 1 ist. Nun wird das Minimum von platz_1 und Anzahl genommen und in aktuell_1 eingefügt und von anzahl abgezogen.

    Die leeren Einträge aus Tabelle1 löschen ich mit einem extra Query.

    Mein Problem ist aktuell die beschränkung, dass nur der Eintrag mit der kleinsten ID berücksichtigt wird.



    Mein Ansatz:

    UPDATE tabelle1 t1, tabelle2 t2 SET t2.aktuell_1 = LEAST(t2.platz_1,t1.anzahl), t1.anzahl = t1.anzahl - t2.aktuell_1 WHERE t2.aktuell_1 = 0 AND t1.user = t2.user AND t1.warteschlange = 1

    So nimmt er aber nun dummerweise irgendeinen Eintrag von t1. Ich müsste aber den mit der niedrigsten ID haben. Jemand ne Idee wie ich das hinbekommen?

    Danke

    CC

  • #2
    Re: Jeweils mit erster Zeile updaten

    Original geschrieben von CC84
    So nimmt er aber nun dummerweise irgendeinen Eintrag von t1. Ich müsste aber den mit der niedrigsten ID haben. Jemand ne Idee wie ich das hinbekommen?
    ich fürchte gar nicht ... das wäre ein GROUP BY mit voriger Sortierung, das kann mysql nicht, was anderes fällt mir als ein Query gerade nicht ein...

    Subquery als Ausweichmöglichkeit, ist halt nur relativ langsam und funktioniert nicht mit jeder Version...

    Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

    bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
    Wie man Fragen richtig stellt

    Kommentar


    • #3
      Ich hab dein Problem nicht verstanden, war was konfus formuliert (oder es ist einfach zu spät; ggf. Beispiel?), aber ich glaube du könntest vielleicht ein ORDER BY und LIMIT gut gebrauchen.
      Für alle die Fehler suchen, gibts gratis tolle Debuggingmöglichkeiten:
      var_dump(), print_r(), debug_backtrace und echo.
      Außerdem gibt es für unsere Neueinsteiger ein hervorragendes PHP Tutorial zu PHP 4 und PHP 5 (OOP)
      Es heißt $array['index'] und nicht $array[index]! Und nein, das ist nicht egal!
      Dieses Thema lesen, um Ärger im Forum und verzögerte Hilfen zu vermeiden.

      Kommentar


      • #4
        Re: Re: Jeweils mit erster Zeile updaten

        Original geschrieben von ghostgambler
        ich fürchte gar nicht ... das wäre ein GROUP BY mit voriger Sortierung, das kann mysql nicht, was anderes fällt mir als ein Query gerade nicht ein...

        Subquery als Ausweichmöglichkeit, ist halt nur relativ langsam und funktioniert nicht mit jeder Version...
        Oje...

        zu genau dem Ergebnis bin ich auch gekommen.

        Habe bisschen rumexperimentiert. Mit einem Order By und anschließendem Group by geht es. Sieht dann von der Konstruktion dann nur sehr hässlich aus, hier mal gerade ohne den Update sondern nur rein der Select der dann als Basis für das Update dienen würde:

        SELECT * FROM
        (
        SELECT t1.*, t2.*
        FROM tabelle1 t1, tabelle t2
        WHERE t1.aktuell_1 = 0 AND t1.user = t2.user
        ORDER BY t1.t1_id
        )
        GROUP BY user

        Zu Shurakai:

        Limit geht nicht, da es viele User gibt und zu jedem User nur ein Beitrag gefunden werden soll. Da ist GROUP BY schon der richtige Weg. Nur leider mit dem Problem, dass wenn Einträge nicht chronologisch in der DB stehen, was ja vorkommen kann, nicht vorhersagbar ist, was GROUP BY zurück gibt.

        Bliebe sonst nur die Fusch Lösung die DB vor der Abfrage nach den IDs zu sortieren. Ich mein es ist hier nicht so HOCH kritisch, wenn da mal was in falscher Reihenfolge läuf, aber sollte natürlich eigentlich nicht.



        So und noch ein kleines Beispiel:

        Tabelle1 enthält 3 Einträge:

        t1_id:2
        user:1
        warteschlange:1
        anzahl:10

        t1_id:1
        user:1
        warteschlange:1
        anzahl:15

        t1_id:3
        user:1
        warteschlange:1
        anzahl:5

        Tabelle2 einen:

        t2_id:512(unwichtig)
        user:1
        platz_1:7
        platz_2:12936(unwichtig)
        aktuell_1:0
        aktuell_2:1234(unwichtig)


        Der Query sollte nun von dem Eintrag t1_id:1 bei anzahl 7 abziehen, die in aktuell_1 in den Eintrag der Tabelle packen.

        Das Problem ist dabei dass man zwar ein GROUP BY auf die User machen kann, dabei würde aber im aktuellen Fall der Eintrag t1_id:2 zurück gegeben.
        Zuletzt geändert von CC84; 04.03.2007, 23:40.

        Kommentar


        • #5
          Re: Re: Re: Jeweils mit erster Zeile updaten

          Original geschrieben von CC84
          SELECT * FROM
          (
          SELECT t1.*, t2.*
          FROM tabelle1 t1, tabelle t2
          WHERE t1.aktuell_1 = 0 AND t1.user = t2.user
          ORDER BY t1.t1_id
          )
          GROUP BY user
          mach doch mal ein EXPLAIN auf den Query

          Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

          bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
          Wie man Fragen richtig stellt

          Kommentar


          • #6
            aha, ehrlich gesagt sagt mir das nun gar nix

            Kommentar


            • #7
              Original geschrieben von CC84
              aha, ehrlich gesagt sagt mir das nun gar nix
              Tjo, dafür kann ich nichts~ Manual hilft, ggf. würde man hier sogar helfen, aber wenn man erst nach dem Result-Tuple fragen muss macht das ganze natürlich nur noch die Hälfte an Spaß...

              Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

              bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
              Wie man Fragen richtig stellt

              Kommentar


              • #8
                Original geschrieben von ghostgambler
                Tjo, dafür kann ich nichts~ Manual hilft, ggf. würde man hier sogar helfen, aber wenn man erst nach dem Result-Tuple fragen muss macht das ganze natürlich nur noch die Hälfte an Spaß...
                Sorry, ich habe mich falsch ausgedrückt. Ich habe schon verstanden, was du wolltest, aber das Ergebnis des Befehls ist für mich nicht durchsichtig.

                Wenn du wolltest, dass ich dir das Ergebnis der Abfrage poste, kann ich das gerne machen, auch wenn ich dafür die DB wie hier beschrieben erst mal erstellen muss, da ich hier wie bereits oben geschrieben eine stark vereinfachte Struktur angegeben habe, die lediglich dazu da ist, das Problem zu beschreiben. Dir wirkliche Struktur anzugeben wäre nur unnötig lang und unübersichtlich.

                Tut mir leid, dass ich mich da gerade falsch ausgedrückt habe.

                Gruß

                CC


                EDIT:

                So ich habe nun das gesamte Update mal geschrieben:

                UPDATE tabelle1 t1,
                tabelle2 t2,
                (
                SELECT t1_id, t2_id
                FROM (

                SELECT t1.t1_id, t2.t2_id, t2.user
                FROM tabelle1 t1, tabelle2 t2
                WHERE t2.aktuell_1 =0
                AND t1.user = t2.user
                ORDER BY t1.t1_id
                )ids
                GROUP BY user
                )ids
                SET t2.aktuell_1 = LEAST( t2.platz_1, t1.anzahl ) ,
                t1.anzahl = t1.anzahl - LEAST( t2.platz_1, t1.anzahl )
                WHERE t1.t1_id = ids.t1_id AND t2.t2_id = ids.t2_id

                So funktioniert es, ist aber in meinen Augen alles nur nich performant.

                Sorry nochmal wegen dem anderen Post, ich hatte in dem Query noch ein paar Fehler drin, weil ich es so runter geschrieben habe.

                Der hier ist getestet und funktioniert, wenns ne schönere Lösung gibt, wäre ich sehr erfreut.

                Ich hätte auch sehr gerne eine Einrückung gemacht, aber dummerweise werden führende Leerzeichen nicht übernommen.

                Noch ein Edit:

                Habe gerade das mal mit 250000 Zeilen in Tabelle1 und 50000 in Tabelle 2 versucht. Nach 3 Minuten habe ich den MYSQL abgeschoßen. Habe mich dann mit EXPLAIN mal durchgearbeitet. Nach dem einfügen eines Index auf t1.user geht es in wenigen Sekunden. Ziel sind aber eigentlich <1 Sekunde zu bleiben. Wenn also noch jemand weiß, wie ich das optimieren kann, immer her damit.
                Zuletzt geändert von CC84; 05.03.2007, 21:05.

                Kommentar

                Lädt...
                X