Tim: MYSQL LIMIT immer am Ende der Anweisung

Hallo,

eigentlich keine Frage, sondern nur eine Hilfe für Suchende, denen es ähnlich ergeht wie mir in den letzten Stunden.

$sql = "select * from tablex  LIMIT 0,10 ORDER BY id desc";

funktioniert nicht!

$sql = "select * from tablex ORDER BY id desc LIMIT 0,10";

so geht's aber ;-)

Bei der Fehlersuche habe ich nirgendwo eine Seite/Manual gefunden, die mir sagt, dass die LIMIT-Anweisung anscheinend immer am Ende stehen muss. Na ja, Rätsel gelöst, hoffe es hilft dem Einen oder Anderen.

  1. Also wenn ich einen SQL Syntaxfehler hätte würde ich nach "mysql limit syntax" suchen. Da kommt eigentlich weit schneller als in ein paar Stunden ein Treffer :-)

    1. Also wenn ich einen SQL Syntaxfehler hätte würde ich nach "mysql limit syntax" suchen. Da kommt eigentlich weit schneller als in ein paar Stunden ein Treffer :-)

      aha, ein kleiner Scherzbold was?

      Na dann zitiere doch mal bitte eine Passage mit Quellangabe die darauf hinweist wo die LIMIT-Anweisung zu stehen hat. Hoffe Du brauchst jetzt nicht Stunden dafür;-)

      1. Na dann zitiere doch mal bitte eine Passage mit Quellangabe die darauf hinweist wo die LIMIT-Anweisung zu stehen hat. Hoffe Du brauchst jetzt nicht Stunden dafür;-)

        https://www.google.de/search?q=mysql+limit+syntax
        Gleich der 1. Treffer, wurde auch schon 2 mal verlinkt. Einmal nach 12 und dann nochmal nach 15 min.

        1. Na dann zitiere doch mal bitte eine Passage mit Quellangabe die darauf hinweist wo die LIMIT-Anweisung zu stehen hat. Hoffe Du brauchst jetzt nicht Stunden dafür;-)
          https://www.google.de/search?q=mysql+limit+syntax
          Gleich der 1. Treffer, wurde auch schon 2 mal verlinkt. Einmal nach 12 und dann nochmal nach 15 min.

          Ich frage ja nicht umsonst nach einem Zitat. Vielleicht übersehe ich das ja aber ich sehe dort nirgendwo explizit so etwas wie "...LIMIT muss in jedem Fall nach ORDER BY erfolgen..."

          1. SELECT
                [ALL | DISTINCT | DISTINCTROW ]
                  [HIGH_PRIORITY]
                  [STRAIGHT_JOIN]
                  [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
                  [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
                select_expr, ...
                [FROM table_references
                [WHERE where_condition]
                [GROUP BY {col_name | expr | position}
                  [ASC | DESC], ... [WITH ROLLUP]]
                [HAVING where_condition]
                [ORDER BY {col_name | expr | position}
                  [ASC | DESC], ...]
                [LIMIT {[offset,] row_count | row_count OFFSET offset}]
                [PROCEDURE procedure_name(argument_list)]
                [INTO OUTFILE 'file_name' export_options
                  | INTO DUMPFILE 'file_name']
                [FOR UPDATE | LOCK IN SHARE MODE]]

            LIMIT kommt nach ORDER BY, welches optional ist.
            Wird ORDER BY nicht angegeben, kommt LIMIT nach der HAVING Clause, welche auch optional ist.
            Wird auch diese nicht angegeben, kommt LIMIT nach GROUP BY. Auch das ist optional, usw.
            Frühestens nach der Expression, welche nicht optional ist, kann also das Limit kommen.

          2. Tach!

            Ich frage ja nicht umsonst nach einem Zitat. Vielleicht übersehe ich das ja aber ich sehe dort nirgendwo explizit so etwas wie "...LIMIT muss in jedem Fall nach ORDER BY erfolgen..."

            Neben der Reihenfolge in der Syntaxbeschreibung steht das sogar wörtlich dort: „In general, clauses used must be given in exactly the order shown in the syntax description. For example, a HAVING clause must come after any GROUP BY clause and before any ORDER BY clause.“

            dedlfix.

            1. Neben der Reihenfolge in der Syntaxbeschreibung steht das sogar wörtlich dort: „In general, clauses used must be given in exactly the order shown in the syntax description. For example, a HAVING clause must come after any GROUP BY clause and before any ORDER BY clause.“

              Danke, das suchte ich.

      2. Ne das war kein Scherz sondern mein Ernst.

        Du hattest ein Problem mit LIMIT in einer SQL Abfrage in mysql. Das sind Stichwörter für eine Suchmaschine. Man kann auch noch "example" oder "Beispiel" oder so mit reinnehmen.
        Oft liegts nur daran nach was man sucht. Dafür kann man ein Gefühl bekommen, probiers doch einfach mal aus.

        Es ist schön Hilfe von jemandem in einem Forum zu bekommen. Aber noch schöner ist es wenn man die Lösung selber findet. Gerade als Anfänger landet man schnell in der nächsten Falle, wenn man dann wieder "lange" auf eine Antwort wartet statt relativ schnell selbst eine zu finden, kommt man nie von der Stelle.

  2. Tach!

    Bei der Fehlersuche habe ich nirgendwo eine Seite/Manual gefunden, die mir sagt, dass die LIMIT-Anweisung anscheinend immer am Ende stehen muss.

    Muss nicht, es kann auch noch etwas danach kommen (wird aber selten verwendet). Die Syntax (und damit die Klausel-Reihenfolge) für alle SQL-Statements steht im MySQL-Handbuch im Kapitel "SQL Statement Syntax". Dort steht dann auch die SELECT Syntax.

    Als kleine Eselsbrücke: Die Klauseln des SELECT-Statements stehen in der Reihenfolge, in der sie (üblicherweise) abgearbeitet werden. Eine Ausnahme bilden dabei lediglich die Select-Expressions, also die Namen der gewünschten Felder und berechnete Ausdrücke. Diese werden zwischen GROUP BY und HAVING ermittelt.

    dedlfix.

  3. Bei der Fehlersuche habe ich nirgendwo eine Seite/Manual gefunden, die mir sagt, dass die LIMIT-Anweisung anscheinend immer am Ende stehen muss. Na ja, Rätsel gelöst, hoffe es hilft dem Einen oder Anderen.

    Nicht am Ende, sondern nach ORDER BY (falls vorhanden)
    http://dev.mysql.com/doc/refman/5.1/de/select.html

  4. Hallo,

    eigentlich keine Frage, sondern nur eine Hilfe für Suchende, denen es ähnlich ergeht wie mir in den letzten Stunden.

    $sql = "select * from tablex  LIMIT 0,10 ORDER BY id desc";

    funktioniert nicht!

    $sql = "select * from tablex ORDER BY id desc LIMIT 0,10";

    so geht's aber ;-)

    Bei der Fehlersuche habe ich nirgendwo eine Seite/Manual gefunden, die mir sagt, dass die LIMIT-Anweisung anscheinend immer am Ende stehen muss. Na ja, Rätsel gelöst, hoffe es hilft dem Einen oder Anderen.

    nur ein Hinweis zum Verständnis:
    LIMIT muß am Ende stehen, denn vorher werden die Daten ausgewählt, danach sortiert, und anschliessend an den Aufrufer zurückgegeben. Dabei werden im Falle dieses Statements nur 10 Sätze zurückgegeben.

    Das kann heissen: Dein Select liefert 10 Mio. Datensätze, die dann sortiert werden und anschliessend werden die ersten 10 Sätze zurückgegeben (zeitaufwendig, da alle 10 Mio. Datensätze sortiert werden müssen).

    Willst Du nur 10 Sätze selektieren und diese sortiert ausgeben, musst Du ein Sub-Select verwenden.

    hth
    AugustQ

    1. Tach!

      LIMIT muß am Ende stehen, denn vorher werden die Daten ausgewählt, danach sortiert, und anschliessend an den Aufrufer zurückgegeben. Dabei werden im Falle dieses Statements nur 10 Sätze zurückgegeben.
      Das kann heissen: Dein Select liefert 10 Mio. Datensätze, die dann sortiert werden und anschliessend werden die ersten 10 Sätze zurückgegeben (zeitaufwendig, da alle 10 Mio. Datensätze sortiert werden müssen).

      Theoretisch ja, praktisch kann MySQL abkürzen, wenn es einen Index verwenden kann, denn dann werden anhand des Indexes die ersten 10 genommen, ohne dass vorher aufwendig zusammengesucht und sortiert werden muss.

      Willst Du nur 10 Sätze selektieren und diese sortiert ausgeben, musst Du ein Sub-Select verwenden.

      Wie soll das gehen?

      dedlfix.

      1. Tach!

        LIMIT muß am Ende stehen, denn vorher werden die Daten ausgewählt, danach sortiert, und anschliessend an den Aufrufer zurückgegeben. Dabei werden im Falle dieses Statements nur 10 Sätze zurückgegeben.
        Das kann heissen: Dein Select liefert 10 Mio. Datensätze, die dann sortiert werden und anschliessend werden die ersten 10 Sätze zurückgegeben (zeitaufwendig, da alle 10 Mio. Datensätze sortiert werden müssen).

        Theoretisch ja, praktisch kann MySQL abkürzen, wenn es einen Index verwenden kann, denn dann werden anhand des Indexes die ersten 10 genommen, ohne dass vorher aufwendig zusammengesucht und sortiert werden muss.

        Willst Du nur 10 Sätze selektieren und diese sortiert ausgeben, musst Du ein Sub-Select verwenden.

        Wie soll das gehen?

        dedlfix.

        Tach!

        zum Punkt #1: meine Aussage bezog sich auf einen full table scan. Es kann sein, daß MySQL (oder MariaDB) unter Verwendung eines Index schneller zum Ziel kommt, da müsste ich erst nachsehen.

        zum Punkt #2: ich habe hier eine Tabelle mit 10 Mio. Datensätzen und verwende die einfach mal. So sieht das au (Darstellung habe ich gekürzt:

          
        mysql> select * from ABDAOK order by PZN limit 10;  
            .....................  
        10 rows in set (14,94 sec)  
          
        mysql> select A.* from (select * from ABDAOK limit 10) A order by PZN;  
            .....................  
        10 rows in set (0,01 sec)  
        
        

        Die Ausgaben unterscheiden sich, da im ersten Fall alle Datensätze sortiert werden müssen und danach werden aus dieser Liste die ersten 10 genommen; im zweiten Fall werden die ersten 10 Datensätze genommen und diese sortiert.

        Schönen Gruß
        AugustQ

        PS: auf dieser Tabelle liegt kein Index.

        1. Tach!

          zum Punkt #1: meine Aussage bezog sich auf einen full table scan. Es kann sein, daß MySQL (oder MariaDB) unter Verwendung eines Index schneller zum Ziel kommt, da müsste ich erst nachsehen.

          Ja, laut Handbuch kürzt MySQL ab, wenn es kann.

          zum Punkt #2: ich habe hier eine Tabelle mit 10 Mio. Datensätzen und verwende die einfach mal. So sieht das au (Darstellung habe ich gekürzt:

          mysql> select * from ABDAOK order by PZN limit 10;
              .....................
          10 rows in set (14,94 sec)

          mysql> select A.* from (select * from ABDAOK limit 10) A order by PZN;
              .....................
          10 rows in set (0,01 sec)

          
          >   
          > Die Ausgaben unterscheiden sich, da im ersten Fall alle Datensätze sortiert werden müssen und danach werden aus dieser Liste die ersten 10 genommen; im zweiten Fall werden die ersten 10 Datensätze genommen und diese sortiert.  
            
          Damit bekommst du zwei völlig verschiedene Ergebnisse. Die zweite Variante nimmt sich einfach die ersten zehn zufällig gewählten Datensätze und sortiert sie. Ob das so gewollt sein kann? Jedenfalls ist das keine Alternative zur ersten Variante und einem Index auf PZN. Denn damit bekommst du die Datensätze mit den zehn kleinsten PZN-Werten.  
            
            
          dedlfix.
          
          1. Hi dedlfix,

            damit bekomme ich zwei unterschiedliche Ergebnissse, genau das, was ich sagen wollte.

            Schau Dir bitte das Original-Statement aus dem Beginn des Threads an. Damit begannen meine Überlegungen.

            Schönen Abend noch.
            AugusstQ

            1. Tach!

              damit bekomme ich zwei unterschiedliche Ergebnissse, genau das, was ich sagen wollte.
              Schau Dir bitte das Original-Statement aus dem Beginn des Threads an. Damit begannen meine Überlegungen.

              Ah, du meinst, die Reihenfolge der Klauseln war bewusst gewählt und sollte eine Abarbeitungsreihenfolge darstellen? Ja, dann wäre die Subquery-Lösung richtig - aber Sinn ergibt das Ganze weiterhin nur sehr wenig, so dass ich nicht davon überzeugt bin, dass das so gewünscht war. Dann hätte eigentlich der OP mit seiner Lösung der syntaktisch richtigen Klauselreihenfolge nicht zufrieden sein dürfen.

              dedlfix.

              1. Guten Abend!

                Ich denke, wir beenden mal die Diskussion, denn so weit auseinander liegen wir nicht.

                Ausgangspunkt waren zwei SQL-Statements, von denen das zweite funktionierte. Und ich wollte einfach mal zeigen:

                - wie man das erste Stmt zum Laufen kriegt

                - und daß dies ein anderes Stmt ist.

                Und der Frager muß jetzt entscheiden, welche Lösung er haben will.

                Schönen Gruß
                AugustQ