Tom: Liste anzeigen vom Aufsetzpunkt X Datensätze

Hello,

DBMS = MySQL >= 5.1

Mit Offset und Limit kann man sich eine Untermenge von Datensätzen nach der gewünschten Sortierung beschaffen.

Nun habe ich aber für den Aufsetzpunkt nicht die Spalte, nach der sortioert werden soll, sondern nur die ID des Aufsetzpunktes. Die Anzeige soll ab dieser ID, aber dann in der gewünschten Sortierung stattfinden, und zwar limitiert.

Wie muss ich die Abfrage formulieren, damit das realisiert werden kann?

Ich muss ja erst den passenden Spaltenwert (ggf. auch mehrere bei Sortierung nach mehreren Spalten) für die betreffende ID holen und dann von dort aus in der gewünschten Sortierung fortfahren.

Hat da einer eine Idee, wie man das in einem einzigen Statement machen könnte?

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
 ☻_
/▌
/ \ Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de
  1. hi,

    ist die ID die kleinste bzw größte in der Liste oder ist diese potenziell auch dazwischen? Der erste fall dürfte einfach sein.

    Gruß Niklas

    --
    Man muss nicht alles wissen, man sollte aber wissen, wo das nicht gewusste zu finden ist.
    1. Hello,

      ist die ID die kleinste bzw größte in der Liste oder ist diese potenziell auch dazwischen? Der erste fall dürfte einfach sein.

      Wir müssen zunächst erstmal annehmen, dass die ID zwar eineindeutig, aber willkürlich ist.
      Wenn es ohne Sonderregeln für die ID nicht geht, müsste ich diese noch einbauen.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
  2. gudn tach!

    Mit Offset und Limit kann man sich eine Untermenge von Datensätzen nach der gewünschten Sortierung beschaffen.

    Nun habe ich aber für den Aufsetzpunkt nicht die Spalte, nach der sortioert werden soll, sondern nur die ID des Aufsetzpunktes. Die Anzeige soll ab dieser ID, aber dann in der gewünschten Sortierung stattfinden, und zwar limitiert.

    wenn ich dich richtig verstehe, willst du in einer sql-query ein variables offset haben. das geht afaics in mysql nicht, auch in 5.6 noch nicht, siehe mysql5.1-manual und mysql5.6-manual. die ausnahmen (prepared statements und stored procedures) bringen dir hier denke ich auch nichts, wenn du nur _eine_ query starten willst. aber vielleicht bin ich auch nur zu muede. *gaehn*

    ansonsten waere es wohl einfach mit
      ... OFFSET FIELD(4, id)
    zu machen. aber das liefert leider nur einen syntax-fehler.

    FIELD ist eine first_index-funktion (mit einem bescheuerten namen, imho).

    Ich muss ja erst den passenden Spaltenwert (ggf. auch mehrere bei Sortierung nach mehreren Spalten) für die betreffende ID holen und dann von dort aus in der gewünschten Sortierung fortfahren.

    dieses vorgehen haette den nachteil, dass der ziedatensatz dadurch nicht notwendig eindeutig bestimmt waere. es koennten ja zwei bzgl. der sortierspalten gleiche datensaetze mit unterschiedlichen ids drin sein; dann wuerde das ergebnis je nachdem kurzer oder laenger sein.

    prost
    seth

    1. Hello,

      wenn ich dich richtig verstehe, willst du in einer sql-query ein variables offset haben.

      Ich schildere mal, wie ich das bisher mache.
      Ich hole den Wert aus der zu ordnenden Spalte über die ID und lege ihn in einer benutzerdefinierten Variable ab.

      Dann suche ich die Datensätzte mit der Where-Bedingung "concat (zu ordnende Spalte, id) >= @merkwert offset, limit.

      Bei umgekehrter Sortierung eben <=.

      Bei Duplicates in der zu ordnenden Spalte habe ich sie dann in der Reihenfolge der IDs. Ohne diesen Trick könnte es in dynamaischen Datenbeständen unangenehme Sprünge geben, wenn man sich durch lange Duplicate-Listen hangeln muss. Man weiß schließlich nicht, wo ein von A bearbeiteter Datensatz physisch landet, während B gerade fröhlich blättert. Die zu ordnende Spalte wird selten geändert; meistens sind es zugehörige Langtexte.

      Nun möchte ich diese zwei Statements aber gerne zusammenfassen zu einem mit subselect. Leider fehlt mir dafür die passende Idee, ob das geht und wie das dann aussehen müsste.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Hi,

        Dann suche ich die Datensätzte mit der Where-Bedingung "concat (zu ordnende Spalte, id) >= @merkwert offset, limit.

        Das’ ja schomma hässlich. Warum CONCAT, warum nicht zwei einzelne Bedingungen?

        Nun möchte ich diese zwei Statements aber gerne zusammenfassen zu einem mit subselect. Leider fehlt mir dafür die passende Idee, ob das geht und wie das dann aussehen müsste.

        Na ob du den Vergleichswert vorher ermittelst, in einer Variablen ablegst, und dann WHERE vergleichswert > @vorher_ermittelter_vergleichswert machst – oder ob du schreibst WHERE vergleichswert > (SELECT vergleichswert FROM …), das macht doch keinen großen Unterschied?

        Wo ist dabei das Problem, wie sieht dein Versuch aus?

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        1. Hello,

          Hi,

          Dann suche ich die Datensätzte mit der Where-Bedingung "concat (zu ordnende Spalte, id) >= @merkwert offset, limit.

          Das’ ja schomma hässlich. Warum CONCAT, warum nicht zwei einzelne Bedingungen?

          Wie sollten die aussehen?
          Ein Kombinationsschlüssel ist nicht dasselbe, wie zwei einzeln geschlüsselte Spalten!

          Nun möchte ich diese zwei Statements aber gerne zusammenfassen zu einem mit subselect. Leider fehlt mir dafür die passende Idee, ob das geht und wie das dann aussehen müsste.

          Na ob du den Vergleichswert vorher ermittelst, in einer Variablen ablegst, und dann WHERE vergleichswert > @vorher_ermittelter_vergleichswert machst – oder ob du schreibst WHERE vergleichswert > (SELECT vergleichswert FROM …), das macht doch keinen großen Unterschied?

          Wer lesen kann, ist eindeutig im Vorteil!

          Ich kenne den einen Teil des Vergleichswertes vorher nicht. Ich kenne nur die ID des ersten Datensatzes in der gewünschten Liste. Und mittels dieser ID muss der vordere Teil des Vergleichswertes erst ermittelt werden.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hi,

            Ein Kombinationsschlüssel ist nicht dasselbe, wie zwei einzeln geschlüsselte Spalten!

            Was du nicht sagst.
            Dass die

            Wie sollten die aussehen?

            -Frage vielleicht leichter zu beantworten wäre, wenn du nicht so allgemein fragen, sondern uns mit ein paar Details erheitern würdest, solltest du eigentlich wissen.

            Ich kenne den einen Teil des Vergleichswertes vorher nicht. Ich kenne nur die ID des ersten Datensatzes in der gewünschten Liste. Und mittels dieser ID muss der vordere Teil des Vergleichswertes erst ermittelt werden.

            Schön. Und was konkret hindert dich daran, das zu tun?

            Wer lesen kann, ist eindeutig im Vorteil!

            Hach, wie üblich – Große Klappe, Tom dahinter.

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. Hello,

              Hach, wie üblich – Große Klappe, Tom dahinter.

              Wie kommt es nur, dass ich DAS eben über Dich gedacht habe?

              Ich hätte es aber ohne deinen Vorstoß nicht ausgesprochen. Geholfen hast Du hier jedenfalls noch nicht, obwohl die Aufgabenstellung hinreichend beschrieben ist. Das liegt aber vermutlich daran, dass Du es auch nicht kannst. :-O

              Aber ich lasse mich gerne vom Gegenteil überraschen und probiere solange eben weiter...

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Hi,

                obwohl die Aufgabenstellung hinreichend beschrieben ist.

                Nein, ist sie nicht.

                Beispieldaten, Beispielquery, kommentiertes erwartetes Ergebnis – das sind die Mindestanforderungen.

                Also, lass’ mal langsam sehen.

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    2. Hello,

      ich habe es jetzt erstmal so gelöst:

        
      select t1.name, t1.id  
      from tabelle t1  
      where t1.name >=  
      (  
         select t2.name from tabelle t2 where t2.id = 24  
      )  
      order by t1.name, t1.id  
      limit 3,5;  
      
      

      und hoffe, dass es so richtig ist.

      bei meinen 30 Musterdatensätzen funktioniert es jedenfalls bisher, wie gewünscht. Die abgefragten Spalten sind hier nur exemplarisch eingesetzt. Wesentlich ist, dass am Anfang immer nur die ID bekannt ist, die den Wert liefert, ab dem dann in dessen Sortierung weiter angezeigt werden soll.

      Was mir noch nicht gefällt, ist dass man sowohl das '>=' als auch in der Order-Klausel ändern muss, wenn anders herum sortiert werden soll. Da stimmt noch 'was nicht...

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Hello,

        ich habe es jetzt erstmal so gelöst:

        und es funktioniert leider nicht, wie gewünscht.

        select t1.name, t1.id
        from tabelle t1
        where t1.name >=
        (
           select t2.name from tabelle t2 where t2.id = 24
        )
        order by t1.name, t1.id
        limit 3,5;

          
        Es wird so immer ab dem ersten DS aus der Sortierung angezeigt, was allerdings nicht nicht sein soll. Wenn auf einer Serie von Duplicates (im Sortierfeld) aufgesetz wird, soll de Serie erst ab demjenigen DS angezeigt werden, der die passende ID hat und von dort aud dann Offset und Limit gerechnet werden.  
          
        Das bekomme ich aber trotz diverser weiterer Versuche nicht hin.  
          
          
          
          
          
        Liebe Grüße aus dem schönen Oberharz  
          
          
        Tom vom Berg  
        ![](http://selfhtml.bitworks.de/Virencheck.gif)  
          
        
        -- 
         ☻\_  
        /▌  
        / \ Nur selber lernen macht schlau  
        <http://bergpost.annerschbarrich.de>
        
        1. Hallo Tom,

          Es wird so immer ab dem ersten DS aus der Sortierung angezeigt, was allerdings nicht nicht sein soll. Wenn auf einer Serie von Duplicates (im Sortierfeld) aufgesetz wird, soll de Serie erst ab demjenigen DS angezeigt werden, der die passende ID hat und von dort aud dann Offset und Limit gerechnet werden.

          Das bekomme ich aber trotz diverser weiterer Versuche nicht hin.

          und ohne ein paar hübsche Beispieldatensätze plus dem gewünschten Ergebnis und Begründung läßt sich höchstens herumraten. *Ich* habe beim besten Willen nicht verstanden, wie Dein Problem genau aussieht. Du hast in diesem Beitrag eine Einschränkung gebracht, die völlig neu ist.

          Freundliche Grüße

          Vinzenz

          1. Hello Vinzenz,

            Es wird so immer ab dem ersten DS aus der Sortierung angezeigt, was allerdings nicht nicht sein soll. Wenn auf einer Serie von Duplicates (im Sortierfeld) aufgesetz wird, soll de Serie erst ab demjenigen DS angezeigt werden, der die passende ID hat und von dort aud dann Offset und Limit gerechnet werden.

            Das bekomme ich aber trotz diverser weiterer Versuche nicht hin.

            und ohne ein paar hübsche Beispieldatensätze plus dem gewünschten Ergebnis und Begründung läßt sich höchstens herumraten. *Ich* habe beim besten Willen nicht verstanden, wie Dein Problem genau aussieht. Du hast in diesem Beitrag eine Einschränkung gebracht, die völlig neu ist.

            Ich werde die Beispieldatensätze liefern. Dauert ein paar Tage, weil ich auch das Umfeld dazu einstellen möchte und hoffe, dass das dann nicht in die Hose geht...

            Also bitte später nochmal nachschauen :-)

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Ich werde die Beispieldatensätze liefern. Dauert ein paar Tage, weil ich auch das Umfeld dazu einstellen möchte und hoffe, dass das dann nicht in die Hose geht...

              Also bitte später nochmal nachschauen :-)

              aber sicher doch :-)

              Freundliche Grüße

              Vinzenz

              1. Hallo Tom,

                Ich werde die Beispieldatensätze liefern. Dauert ein paar Tage,

                eher ein paar Wochen ;-)

                Freundliche Grüße

                Vinzenz

                1. Tach.

                  Ich werde die Beispieldatensätze liefern. Dauert ein paar Tage,

                  eher ein paar Wochen ;-)

                  Oder noch länger?

                  --
                  Always remember that you are unique. Just like everybody else.
                  1. Hello,

                    Oder noch länger?

                    Ja, noch länger. Der Rechner, auf dem das drauf ist, ist "vorübergehend gestorben". Ich habe doch leider nur noch alten Plunder...

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Tach.

                      Ja, noch länger. Der Rechner, auf dem das drauf ist, ist "vorübergehend gestorben". Ich habe doch leider nur noch alten Plunder...

                      Nur noch dies, bevor der Thread in der Versenkung verschwindet:

                      Ich verstehe zwar nicht, wieso Du für ein paar aussagekräftige Beispieldatensätze unbedingt diesen Rechner brauchst, aber eigentlich ist's auch egal. Ich war bloß neugierig, was es mit diesem Problem auf sich hat, bin aber aus Deiner Beschreibung genauso schlau geworden wie Vinzenz.

                      --
                      Always remember that you are unique. Just like everybody else.
                      1. Hello,

                        Ich verstehe zwar nicht, wieso Du für ein paar aussagekräftige Beispieldatensätze unbedingt diesen Rechner brauchst,

                        weil dort das Problem schon fertig formuliert drauf ist.
                        Ich versuche es nochmal, auch wenn ich es jetzt vielleicht etwas umständlich schildere:

                        Datensätze

                        id      name

                        1       Albers
                        7       Müller
                        99      Schulze
                        2       Müller
                        15      Meier
                        100     Behrens
                        30      Gehricke
                        55      Paulsen
                        3       Müller

                        Wenn man die jetzt sortioeren würde über name, id, dann käme sowas dabei heraus:

                        1       Albers
                        100     Behrens
                        30      Gehricke
                        2       Müller
                        3       Müller
                        7       Müller
                        15      Meier
                        55      Paulsen
                        99      Schulze

                        Ich habe jetzt nur die ID 30

                        Ab dieser ID als Aufsetzpunkt soll ich 5 Datensätze ausgeben in der Sortierung nach name,id

                        30      Gehricke
                        2       Müller
                        3       Müller
                        7       Müller
                        15      Meier

                        Wie kann ich das möglichst in einer einzigen Abfrage bewerkstelligen?

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de
                        1. Hello,

                          Hello,

                          Ich verstehe zwar nicht, wieso Du für ein paar aussagekräftige Beispieldatensätze unbedingt diesen Rechner brauchst,

                          weil dort das Problem schon fertig formuliert drauf ist.
                          Ich versuche es nochmal, auch wenn ich es jetzt vielleicht etwas umständlich schildere:

                          Datensätze

                          id      name

                          1       Albers
                          7       Müller
                          99      Schulze
                          2       Müller
                          15      Meier
                          100     Behrens
                          30      Gehricke
                          55      Paulsen
                          3       Müller

                          Wenn man die jetzt sortioeren würde über name, id, dann käme sowas dabei heraus:

                          1       Albers
                          100     Behrens
                          30      Gehricke
                          15      Meier
                          2       Müller
                          3       Müller
                          7       Müller
                          55      Paulsen
                          99      Schulze

                          Ich habe jetzt nur die ID 30

                          Ab dieser ID als Aufsetzpunkt soll ich 5 Datensätze ausgeben in der Sortierung nach name,id

                          30      Gehricke
                          15      Meier
                          2       Müller
                          3       Müller
                          7       Müller

                          Wie kann ich das möglichst in einer einzigen Abfrage bewerkstelligen?

                          War ja klar, dass ich da jetzt einen Fehler in die Problembeschreibung reinbaue :-O

                          Liebe Grüße aus dem schönen Oberharz

                          Tom vom Berg

                          --
                           ☻_
                          /▌
                          / \ Nur selber lernen macht schlau
                          http://bergpost.annerschbarrich.de
                          1. Hello,

                            also jetzt habe ich mir extra das Schmalz aus dem Gehirn gequetscht, und jetzt guckt auch keiner mehr *traurig*

                            Datensätze

                            id      name

                            1       Albers
                            7       Müller
                            99      Schulze
                            2       Müller
                            15      Meier
                            100     Behrens
                            30      Gehricke
                            55      Paulsen
                            3       Müller

                            Wenn man die jetzt sortioeren würde über name, id, dann käme sowas dabei heraus:

                            1       Albers
                            100     Behrens
                            30      Gehricke
                            15      Meier
                            2       Müller
                            3       Müller
                            7       Müller
                            55      Paulsen
                            99      Schulze

                            Ich habe jetzt nur die ID 30

                            Ab dieser ID als Aufsetzpunkt soll ich 5 Datensätze ausgeben in der Sortierung nach name,id

                            30      Gehricke
                            15      Meier
                            2       Müller
                            3       Müller
                            7       Müller

                            Wie kann ich das möglichst in einer einzigen Abfrage bewerkstelligen?

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            http://bergpost.annerschbarrich.de
                            1. Tach!

                              Ich habe jetzt nur die ID 30
                              Ab dieser ID als Aufsetzpunkt soll ich 5 Datensätze ausgeben in der Sortierung nach name,id
                              Wie kann ich das möglichst in einer einzigen Abfrage bewerkstelligen?

                              Ich glaube nicht, dass das ohne Stored Procedure geht, bei der du dich durch die sortierte Ergebnismenge hangelst und alles bis zum Auftreten der ID verwirfst, ab dann alles in eine temporäre Tabelle einfügst, die du dann zum Schluss ausgibst.

                              Da fällt mir noch eine weitere Lösung mit einer Variable ein, die zunächst auf NULL gesetzt wird. In einem SELECT mit IF() oder CASE prüfst du auf deine ID, setzt daraufhin deine Variable mit diesem Wert (oder was anderem, das TRUE entspricht). Das ist auch das eine Teilergebnis des Ausdrucks. Der Else-Zweig gibt NULL zurück. Dieses IF/CASE kommt als zweiter Ausdruck in ein COALESCE(). Der erste Ausdruck ist die Variable. Das Ergebnis von COALESCE() wertest du boolesch aus und selektierst so deine Datensätze aus einer sortiert vorliegenden Menge (die wird aus einem Subselect kommen müssen). Solange die Variable immer noch NULL ist, wird der zweite Audruck ausgewertet, bei dem auf die ID getestet und gegebenenfalls die Variable entNULLT wird. Das Ergebnis ist also entweder kein NULL bei der gesuchten ID oder NULL, und der Datensatz wird genommen oder nicht. Danach zieht die Variable (mit != NULL) im ersten Parameter und der Datensatz wird genommen.

                              Das Handbuch rät davon zwar ab: "As a general rule, you should never assign a value to a user variable and read the value within the same statement. You might get the results you expect, but this is not guaranteed.", aber ich kann mir vorstellen, dass durch die Verschachtlung die Verarbeitungsreihenfolge eindeutig wird. Es darf nur nicht irgendein Index die Reihenfolge ändern. Das sollte eigentlich nicht vorkommen und MySQL müsste bei diesem Vergleich immer einen Full Table Scan auf die Subselect-Menge anwenden (was sich mit einem EXPLAIN prüfen lassen sollte[1]). Das ist dann auch der Nachteil an beiden Lösungsansätzen: performant wirst du das bei großen Datenmengen nicht bekommen, weil MySQL immer zu Fuß durch die Datenmenge laufen muss.

                              Nicht dass ich in meiner Prosa einen Fehler drin habe, deswegen hier in Codeform, wie ich mir das denke:

                              SET @marker = NULL;  
                              SELECT * FROM (SELECT * FROM tabelle ORDER BY name) WHERE COALESCE(@marker, IF(id=30, @marker := 1, NULL))
                              

                              Erklärungsversuch, warum es nicht bereits eine Funktion gibt, die bis zu oder ab einem bestimmten Merkmal alles nimmt: MySQL arbeitet (wie eigentlich alle SQL-Systeme) mit Datenmengen ohne definierte Reihenfolge. Es ist nicht unbedingt vorhersehbar, ob der Optimierer einen Index nimmt oder nicht, so dass die Reihenfolge nicht feststeht, in der er die Datensätze auswertet. Und das macht es im Prinzip unmöglich, eine solche Funktion mit deterministischem Ergebnis zu schreiben. Die Variablen-Lösung geht davon aus (die andere eigentlich auch), dass man die Suchreihenfolge festgelegt bekommt.

                              [1] Zu prüfen wäre, dass kein Index _verfügbar_ ist. Wenn nur keiner genommen wird, heißt das nicht, dass das immer so bleibt. Der Ausführungsplan ändert sich auch mit der Anzahl der Datensätze.

                              dedlfix.

  3. Hello,

    tut sich hier noch was?

    Ich würde mich freuen, wenn Ihr mich jetzt nicht hängen lassen würdet.
    https://forum.selfhtml.org/?t=210375&m=1440617

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://restaurant-zur-kleinen-kapelle.de