Matze: MySQL - Limit-Problem

Hallo,

ich habe bzw. hätte ich gern ein Blättermenü für eine Bildergallerie.
Durch die ausgewählte Seite als Parameter kann ich ohne Probleme die anzuzeigenden Datensätze berechnen.
Nur mit dem Statement habe ich ein Problem.

Momentan wird meine Limit-Klausel auf die Bilder angewendet und nicht auf deren Kategorien.

Das Statement:

"SELECT uploadedfiles.fileName AS fileName,  
    uploadedfiles.fileSize AS fileSize,  
    uploadedfiles.id AS fId,  
    uploadcategorys.categoryName AS catName,  
    uploadcategorys.id AS catId  
FROM uploadcategorys  
LEFT JOIN uploadedfiles ON uploadedfiles.categoryId = uploadcategorys.id  
ORDER BY catId DESC  
LIMIT ?, ?"

Wobei die ? mittels prepared Statement ersetzt werden.
Das Funktioniert soweit auch richtig. Tut aber nicht das, was ich will.

Als Beispiel LIMIT 0, 5 gibt mir brav die ersten 5 Bilder, nicht aber die ersten 5 Kategorien.

Kann mir bitte jemand sagen wie ich das Statement modifizieren kann?
Oder komm ich nicht drumrum ein zusätzliches Statement für die Datei-Tabelle zu schreiben?

Danke und Grüße, Matze

  1. moin,

    Als Beispiel LIMIT 0, 5 gibt mir brav die ersten 5 Bilder, nicht aber die ersten 5 Kategorien.

    es tut schon das, was du ihm sagst, was es tun soll. du hast eine 1:n beziehung zwischen kategorien und den zugehörigen bildern (meiner meinung müsste es sogar n:m sein, aber ohne fachlichen hintergrund, kann man nur tippen).

    je nachdem wieviele bilder in -> einer <- kategorie sind, bekommst du auch eine entsprechende anzahl an datensätze durch die abfrage zurück geliefert. sprich wenn du immer 5 datensätze blättern willst, kann es gut sein, dass du mehrere seiten für eine kategorie bekommst. du musst dir also erst mal überlegen, wie du das abbilden willst, das eine kategorie mehrere bilder haben kann und wie du darüber blättern willst.

    Ilja

    1. Hey Ilja,

      es tut schon das, was du ihm sagst, was es tun soll. du hast eine 1:n beziehung zwischen kategorien und den zugehörigen bildern (meiner meinung müsste es sogar n:m sein, aber ohne fachlichen hintergrund, kann man nur tippen).

      ja, es ist eine 1:n Beziehung. Eine n:m Beziehung schien mir nicht notwendig.
      Es gibt z.B. keine Bilder ohne Kategorie.

      je nachdem wieviele bilder in -> einer <- kategorie sind, bekommst du auch eine entsprechende anzahl an datensätze durch die abfrage zurück geliefert.

      Ich habe bemerkt, dass auch die Kategorie mitgezählt wird. Es werden also nicht 5 Bilder (falls vorhanden) angezeigt, sondern korrekt 5 Datensätze. Also Kategorie + 4 Bilder. Kann ich soweit auch alles nachvollziehen.

      du musst dir also erst mal überlegen, wie du das abbilden willst, das eine kategorie mehrere bilder haben kann und wie du darüber blättern willst.

      Meinst du das bei der Tabellen-Struktur oder bei dem Statement?
      Eine n:m Beziehung erschien mir, wie gesagt, unnötig und bei dem Statement beiss ich mir irgendwie die Zähne aus.

      Der Hinweis auf DISTINCT hat mir leider nicht weiter geholfen oder ich habe es falsch angewendet (laut Handbuch vor dem Spaltennamen im SELECT-Bereich).

      Danke und Grüße, Matze

      1. moin,

        ja, es ist eine 1:n Beziehung. Eine n:m Beziehung schien mir nicht notwendig.
        Es gibt z.B. keine Bilder ohne Kategorie.

        das hat nichts mit n:m zu tun, ob es bilder ohne kategorie gibt (starke oder schwache beziehungen), sondern ob ein bild in mehreren kategorien vorkommen kann. ich würde das grundsätzlich so sehen, es hängt aber von deinem konkreten fall ab.

        Ich habe bemerkt, dass auch die Kategorie mitgezählt wird. Es werden also nicht 5 Bilder (falls vorhanden) angezeigt, sondern korrekt 5 Datensätze. Also Kategorie + 4 Bilder. Kann ich soweit auch alles nachvollziehen.

        nein, bei 5 bilder in einer kategorie, wirst du 5 datensätze bekommen. gibt es kein bild der kategorie, bekommst du einen datensatz zurück, dann du einen OUTER JOIN gemacht hast.

        Meinst du das bei der Tabellen-Struktur oder bei dem Statement?

        sowohl als auch, erst mal die struktur festlegen und dann sich klar machen, wie ich es anzeigen will. habe ich beides, ist die abfrage ein kinderspiel.

        Ilja

        1. Ok, ich habe mich nochmals mit dem Handbuch rumgeschlagen.
          Rausgekommen ist jetzt das:

          SELECT *  
          FROM `uploadcategorys`  
          LEFT JOIN `uploadedfiles` ON ( `uploadedfiles`.`categoryId` = `uploadcategorys`.`id` )  
          WHERE `uploadcategorys`.`id` IN (SELECT `id` FROM `uploadcategorys` ORDER BY `id` ASC LIMIT 0, 3)  
          ORDER BY `uploadcategorys`.`id` DESC
          

          Ich habe das Gefühl es müsste stimmen. Meinem MySQL gefällt aber das LIMIT nicht.

          #1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

          Gibt es eine Version die LIMIT an dieser Stelle unterstützt? Oder muss ich die Tabellen ändern (zur Zeit InnoDb)?
          Oder ist das schon wieder völliger Murks?

          Danke und Grüße, Matze

          1. moin,

            Gibt es eine Version die LIMIT an dieser Stelle unterstützt? Oder muss ich die Tabellen ändern (zur Zeit InnoDb)?

            kann ich dir nicht genau sagen, würde aber darauf tippen, dass es keine version von mysql gibt, die das unterstützt.

            Oder ist das schon wieder völliger Murks?

            sagen wir es mal so, es ist "unschön", wie meine ex zu pflegen sagte. was spricht dann dagegen, daraus zwei abfragen zu machen, wie ich dir schon mal nahe gelegt habe ?

            Ilja

            1. Hey Ilja,

              sagen wir es mal so, es ist "unschön", wie meine ex zu pflegen sagte. was spricht dann dagegen, daraus zwei abfragen zu machen, wie ich dir schon mal nahe gelegt habe ?

              1. MySQL-Abfragen brauchen Zeit. Je weniger man davon abschickt, umso besser.
              (kommt natürlich auch aufs Statement an.
              2. Die weitere Verarbeitung geht von 1 Array aus. Das könnte ich zwar auch ändern oder das Array einfach nachbauen, das ist mit der richtigen Abfrage aber überflüssig.

              Grüße, Matze

              1. moin,

                Das könnte ich zwar auch ändern oder das Array einfach nachbauen, das ist mit der richtigen Abfrage aber überflüssig.

                zum einen können zwei abfragen performanter sein als eine komplexe, das hängt immer von den fall ab. zum anderen habe ich noch keine vorstellung davon, wie das "ohne LIMIT in unterabfragen" bei mysql mit nur einer abfrage gehen soll. ich würde wie gesagt immer noch zwei abfragen draus machen.....

                Ilja

                1. zum einen können zwei abfragen performanter sein als eine komplexe, das hängt immer von den fall ab.

                  Sagte ich ja.

                  zum anderen habe ich noch keine vorstellung davon, wie das "ohne LIMIT in unterabfragen" bei mysql mit nur einer abfrage gehen soll. ich würde wie gesagt immer noch zwei abfragen draus machen.....

                  Dann hast du meinen letzten Beitrag überlesen.

                  Ich habe die Abfrage sogar soweit erweitert, dass ich die Kategorien per LIMIT "steuere" und mir nur die anzeigen lasse, die auch tatsächlich Bilder haben (brauch ich aber nur für 1 speziellen Fall).

                  Um dir das Problem mit der "zweiten Abfrage" nochmal zu verdeutlichen;
                  meine Lösung:
                  1. Abfrage um Einstellungen zu übernehmen (z.B. Einträge pro Seite)
                  2. Abfrage nach der Anzahl der Einträge um das Blättermenü zu erstellen
                  3. Abfrage der eigentlichen Daten + Ausgabe

                  deine Lösung:
                  1., 2. siehe meine Lösung
                  3. Abfrage und Ausgabe der Kategorien - n pro Seite
                  4. n Abfragen um die Bilder zu ermitteln

                  Bei z.B. 10 Kategorien pro Seite, habe ich schon 13 Abfragen im Gegensatz zu 3 mit meiner Lösung. Das potenziert sich natürlich umso mehr Kategorien pro Seite ausgegeben werden sollen. Im Extrem-Fall alle.

                  Da kommt mir eine erweiterte Abfrage um einiges eleganter vor.

                  Grüße, Matze

                  1. moin,

                    Dann hast du meinen letzten Beitrag überlesen.

                    habe ich in der tat. ich bin wie gesagt kein mysql experte, aber offenbar geht es als unterabfrage in der from klausel.

                    1. Abfrage und Ausgabe der Kategorien - n pro Seite
                    2. n Abfragen um die Bilder zu ermitteln

                    das ist nicht der fall, ich sprach immer aus einer abfrage zwei zu machen und zwar in jedem fall zwei abfragen.

                    Bei z.B. 10 Kategorien pro Seite, habe ich schon 13 Abfragen im Gegensatz zu 3 mit meiner Lösung.

                    in diesem beispiel hättest du bei mir 4 abfragen und nicht 13. wenn du schon in der ersten abfrage alle kategorien hast, warum solltest du pro kategorie eine abfrage machen, wenn du alle bilder zusammen bekommen kannst  ?

                    Ilja

                    1. Hey Ilja,

                      in diesem beispiel hättest du bei mir 4 abfragen und nicht 13. wenn du schon in der ersten abfrage alle kategorien hast, warum solltest du pro kategorie eine abfrage machen, wenn du alle bilder zusammen bekommen kannst  ?

                      da hast du Recht. Ich habe dich einfach falsch verstanden.
                      Ich dachte halt du würdest in der Schleife, die die Kategorien ausgibt, die Abfrage nach den Bildern unterbringen wollen.

                      So ergibt das natürlich alles sehr viel mehr Sinn und in der Tat würde die 1 Abfrage mehr dann auch nicht mehr weh tun.

                      Mich stört jetzt aber auch nicht, dass ich es über 1 Abfrage lösen konnte ;)

                      Grüße, Matze

  2. Hallo,

    ORDER BY catId DESC
    LIMIT ?, ?"[/code]

    Als Beispiel LIMIT 0, 5 gibt mir brav die ersten 5 Bilder, nicht aber die ersten 5 Kategorien.

    Irgendwie falsch gedacht. Du bekommst weder Bilder noch Kategorien, sondern Datensätze der Datenbank.

    Die sortierst du absteigend nach catID, also bekommst du die fünf Sätze mit den höchsten catID, vielleicht fünfmal dieselbe catID und zufällig die ersten fünf fileName.

    Fünf verschiedene catID bekommst du mit
    SELECT ... DISTINCT catID

    Gruß, Schorsch

  3. Als Beispiel LIMIT 0, 5 gibt mir brav die ersten 5 Bilder, nicht aber die ersten 5 Kategorien.

    Nein, deine Abfrage gibt dir die ersten fünf Einträge  in uploadcategorys sortiert nach deren ID, ich glaub nicht, dass du das willst.

    Kann mir bitte jemand sagen wie ich das Statement modifizieren kann?

    Soweit ich das sehe musst du die Tabellen in dem join umdrehen.

    Struppi.

    1. Nein, deine Abfrage gibt dir die ersten fünf Einträge  in uploadcategorys sortiert nach deren ID, ich glaub nicht, dass du das willst.

      Ich hab mich wohl etwas ungeschickt ausgedrückt.
      Ich möchte bestimmte mit LIMIT festgelegte Kategorien aus Tabelle A und alle dazugehörigen Bilder aus Tabelle B.

      Jetzt sitz ich schon so lange daran und komm irgendwie zu keinem Ergebnis.
      Ich hab versucht irgendwas mit GROUP BY zu erreichen aber bin damit auch gescheitert.

      Mein Testcode sieht jetzt so aus:

      SELECT  
          uploadcategorys.id AS catId,  
          uploadedfiles.id AS fId  
      FROM uploadedfiles			  
      INNER JOIN uploadcategorys ON uploadedfiles.categoryId = uploadcategorys.id
      

      Da fehlt aber jedes ORDER BY und GROUP BY (brauch ich das) und natürlich kein LIMIT. Ich weiß nicht wo ich ansetzen soll :(

      Danke und Grüße, Matze

      1. moin,

        Ich möchte bestimmte mit LIMIT festgelegte Kategorien aus Tabelle A und alle dazugehörigen Bilder aus Tabelle B.

        das problem ist, dass du eine unbestimmte anzahl von bildern pro kategorie hast. insofern sehe zumindestens ich keine lösung mit LIMIT (andere wissen da sicherlich mehr, die sich mit mysql besser auskennen). deshalb würde ich es in zwei abfragen aufteilen. die erste abfragen ermittelt die daten aus der Tabelle kategorien und war ohne die bilder. dann kannst du wieder LIMIT einsetzen. die zweite abfrage ermittelt anhand des PK aus der tabelle kategorien die entsprechenden bilder, die du auch auf der seite anzeigen willst.

        eine andere möglichkeit es mit einer abfrage zu machen wären unterabfragen, was aber ein wenig komplexer werden kann.

        Ilja

        1. die zweite abfrage ermittelt anhand des PK aus der tabelle kategorien die entsprechenden bilder, die du auch auf der seite anzeigen willst.

          korrektur, dass ist natürlich nicht die tabelle kategorie, sondern die tabelle, wo die bilder sind. noch mal mein hinweis, es könnte sich auch bei dir um eine n:m beziehung handeln.

          PS: an die redaktion, wann kommt die edit-funktion von beiträgen ?

          Ilja

          1. Hi!

            PS: an die redaktion, wann kommt die edit-funktion von beiträgen ?

            Ich bin zwar kein Redaktionsbestandteil, aber: Erst dann, wenn auch das Forum durch ein Wiki abgelöst wird*). Dann kannst du editieren wie du lustig bist, und durch die Versionsverwaltung auch nicht hinterher rausreden, dass du XYZ gar nicht gesagt hast ...

            *) Solcherart Pläne sind mir {$goetze}seidank noch nicht zu Ohren gekommen.

            Lo!

            1. moin,

              Ich bin zwar kein Redaktionsbestandteil, aber: Erst dann, wenn auch das Forum durch ein Wiki abgelöst wird*). Dann kannst du editieren wie du lustig bist, und durch die Versionsverwaltung auch nicht hinterher rausreden, dass du XYZ gar nicht gesagt hast ...

              scheint eine spezifische besorgnis hier im forum zu sein, die ich ehrlich gesagt so nicht teilen kann. in anderem foren kann man editieren und es gibt damit kaum probleme, eher im gegenteil, die vorteile davon wiegen die nachteile deutlich auf.

              Ilja

              1. Moin!

                Ich bin zwar kein Redaktionsbestandteil, aber: Erst dann, wenn auch das Forum durch ein Wiki abgelöst wird*). Dann kannst du editieren wie du lustig bist, und durch die Versionsverwaltung auch nicht hinterher rausreden, dass du XYZ gar nicht gesagt hast ...

                scheint eine spezifische besorgnis hier im forum zu sein, die ich ehrlich gesagt so nicht teilen kann. in anderem foren kann man editieren und es gibt damit kaum probleme, eher im gegenteil, die vorteile davon wiegen die nachteile deutlich auf.

                Ich darf dir persönlich versichern, dass ich schon auf unangenehme Weise Opfer von nachträglicher Editierbarkeit von Beiträgen in einem Board geworden bin. Es ging z.B. um eine etwas hitzigere Diskussion, in der der Diskussionspartner seine Beiträge auf meine Gegenrede hin nachträglich nochmal umeditiert hat, so dass es hinterher völlig blödsinnig aussah, was ich da angegriffen hatte.

                Sorry, aber nur weil's manchmal blöd ist, dass irgendwelche Tippfehler und fehlende Ergänzungen in ein Posting reinkommen, werde ich nicht die Verlässlichkeit und Stabilität des einmal veröffentlichten Wortes in Frage stellen. Das, was gepostet ist, steht fest. Kann beantwortet werden. Ändert sich nicht mehr.

                - Sven Rautenberg

                1. moin,

                  Ich darf dir persönlich versichern, dass ich schon auf unangenehme Weise Opfer von nachträglicher Editierbarkeit von Beiträgen in einem Board geworden bin.

                  geht meiner meinung nach am thema vorbei. man kann immer beispiele aufführen, aber letztlich muss man abwägen. und bei solchen beiträgen, wo man versucht jemand anderen dumm aussehen zu lassen, die sind es eh nicht wert, dass man ihnen große beachtung schenkt. da sollte man einfach drüber stehen.

                  Sorry, aber nur weil's manchmal blöd ist, dass irgendwelche Tippfehler und fehlende Ergänzungen in ein Posting reinkommen, werde ich nicht die Verlässlichkeit und Stabilität des einmal veröffentlichten Wortes in Frage stellen. Das, was gepostet ist, steht fest. Kann beantwortet werden. Ändert sich nicht mehr.

                  mit blödheit hat das wenig zu tun und tippfehler sind mir egal. aber wenn es um fachliche dinge geht, weil man etwas wichtiges vergessen hat zu erwähnen, oder eine tabelle falsch benannt hat, etc., das ist für mich viel wichtiger als irgendwelche persönlichen kleinkriege. und die verlässlichkeit und die stabilität in anderen foren, wo man editieren kann ist sehr hoch.

                  Ilja

                  1. Hi!

                    mit blödheit hat das wenig zu tun und tippfehler sind mir egal. aber wenn es um fachliche dinge geht, weil man etwas wichtiges vergessen hat zu erwähnen, oder eine tabelle falsch benannt hat, etc., das ist für mich viel wichtiger als irgendwelche persönlichen kleinkriege.

                    Dazu kann man einen Folgebeitrag erstellen und sich korrigieren. Wie auch immer, die Wünsche nach der Realisierung einer Edit-Funktion scheitern schon allein deswegen weil es keinen gibt, der sie implementieren könnte oder möchte.

                    Lo!

                    1. moin,

                      ... weil es keinen gibt, der sie implementieren könnte oder möchte.

                      mag sein, ist für mich aber eine grundsätzliche frage, wohin die reise von selfhtml geht. frischer wind würde mir gefallen. ich habe eher den eindruck, alles soll so bleiben wie es ist, das kann aber auch gut täuschen. alleine den namen "selfhtml" halte ich nicht mehr für up to date.

                      Ilja

  4. Nach verzweifelter Suche habe ich nun endlich die Lösung gefunden.
    Fürs Archiv:

      
    SELECT uploadcategorys.id catId,  
           uploadcategorys.categoryName catName,  
           uploadedfiles.id fId,  
           uploadedfiles.fileName fileName,  
           uploadedfiles.fileSize fileSize  
    FROM (SELECT id, categoryName  
          FROM uploadcategorys  
          ORDER BY id DESC  
          LIMIT ?, ?)  
         uploadcategorys  
    LEFT JOIN uploadedfiles  
    ON uploadcategorys.id = uploadedfiles.categoryId  
    ORDER BY uploadcategorys.id DESC, uploadedfiles.id  
    
    

    uff...

    ...und wieder zurück zu C++ :)

    Grüße, Matze