Markus**: Datenbanken...

Hallo Forum!

Wie kommt es eigentlich, dass man bei MSSQL und Oracle alle ausgewählten spalten in der GROUP BY Klausel angeben muß, bei MySQL jedoch auf nur EINE Spalte Gruppieren kann?

Ich finde die MySQL-Variante deutlich angenehmer.

  1. Die SQL-Syntax ist in verschiedenen ISO-Standards definiert - ein schlauer DBMS-Anbieter unstützt zumindest den aktuellen Grundumfang bzw. zumindest SQL:1999- darüberhinaus kann jeder machen was er will.

  2. Hallo,

    Wie kommt es eigentlich, dass man bei MSSQL und Oracle alle ausgewählten spalten in der GROUP BY Klausel angeben muß,

    muss man ja gar nicht. Nur alle Spalten, auf die keine Aggregatsfunktion angewandt wird. Das ist übrigens im SQL-Standard so festgelegt.

    bei MySQL jedoch auf nur EINE Spalte Gruppieren kann?
    Ich finde die MySQL-Variante deutlich angenehmer.

    Ich halte dies eher für einen Bug als ein Feature. Es führt immer wieder zu Fragen hier im Forum, weil eine Abfrage nicht das Ergebnis liefert, was der Benutzer erwartet.

    Wenn eine Spalte innerhalb der Gruppe verschiedene Werte aufweist, ist der von MySQL zurückgegebene Wert nicht vorhersagbar. SQL-Novizen, die nur MySQL kennen, nehmen an, es würde immer der Wert zurückgegeben, den sie bei ihren ein, zwei Testabfragen erhalten haben und der zufälligerweise der Wert ist, den sie haben möchten, ein Beispiel: </archiv/2006/8/t134684/#m873900>

    Nein, was MySQL da macht, ist für mich - auch wenn das Verhalten dokumentiert ist - keine besonders gute Idee.

    Freundliche Grüße

    Vinzenz

    1. moin,

      Nein, was MySQL da macht, ist für mich - auch wenn das Verhalten dokumentiert ist - keine besonders gute Idee.

      als ergänzung, wenn ich mich richtig an die dokumentation erinnere, so erlaubt auch mysql es nicht, grundsätlich jede x-beliebige spalte bei der verwendung von GROUP BY mit auszugeben, sondern eben nur die spalten, die innerhalb der gruppierung eindeutig sind.

      der hintergrund dafür ist performance, sprich man verspricht sich einen zeitgewinn, indem man nicht noch zusätzlich über spalten gruppiert, wenn die eindeutigkeit schon durch andere spalten gegeben ist. das dbms muss nämlich über jede spalte in der group by klausel sortieren. je mehr spalten dort angegeben werden, desto mehr sortierarbeit.

      und dort liegt dann auch das problem, weil mysql sich eben arbeit sparen will, kann es nicht mehr überprüfen, ob die spalten innerhalb der gruppierung eindeutig sind, auch wenn darüber nicht gruppiert wurde, sondern geht davon aus, dass jeder anwender das schon richtig interpretieren wird. das ist aber fatal und erweißt sich in der praxis als nicht tauglich, mal davon abgesehen, dass es stark von den inhalten abhängt.

      also, nicht glauben man kann bei mysql jede beliebige spalte mit ausgeben, nur weil es keine fehlermeldung gibt, das ist nämlich falsch.

      Ilja

      1. Hi,

        als ergänzung, wenn ich mich richtig an die dokumentation erinnere, so erlaubt auch mysql es nicht, grundsätlich jede x-beliebige spalte bei der verwendung von GROUP BY mit auszugeben, sondern eben nur die spalten, die innerhalb der gruppierung eindeutig sind.

        Was meinst du hier mit eindeutig?

        „MySQL extends the use of GROUP BY to allow selecting fields that are not mentioned in the GROUP BY clause.”
        [http://dev.mysql.com/doc/refman/5.1/en/select.html]

        der hintergrund dafür ist performance, sprich man verspricht sich einen zeitgewinn, indem man nicht noch zusätzlich über spalten gruppiert, wenn die eindeutigkeit schon durch andere spalten gegeben ist. das dbms muss nämlich über jede spalte in der group by klausel sortieren. je mehr spalten dort angegeben werden, desto mehr sortierarbeit.

        Mit Performance meinst du hier Performance beim *Schreiben* von Queries, in dem man auf Gruppierungen verzichtet?
        Wenn man damit leben kann, für solche Spalten wie von Vinzenz erwähnt einen „zufälligen“ Wert zu erhalten, dann kann man das machen.

        also, nicht glauben man kann bei mysql jede beliebige spalte mit ausgeben, nur weil es keine fehlermeldung gibt, das ist nämlich falsch.

        Wie soll sich denn sonst „nicht können“ äussern, wenn nicht mit einer Fehlermeldung?

        Man kann die Spalten angeben, die man angeben will - und erhält ein Ergebnis.

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
        1. moin,

          Was meinst du hier mit eindeutig?
          Man kann die Spalten angeben, die man angeben will - und erhält ein Ergebnis.

          du hättest den link weiter gehen sollen, dort steht: "When using this feature, all rows in each group should have the same values for the columns that are ommitted from the GROUP BY part."

          http://dev.mysql.com/doc/refman/5.1/en/group-by-hidden-columns.html

          Mit Performance meinst du hier Performance beim *Schreiben* von Queries, in dem man auf Gruppierungen verzichtet?
          Wenn man damit leben kann, für solche Spalten wie von Vinzenz erwähnt einen „zufälligen“ Wert zu erhalten, dann kann man das machen.

          nein, das macht nicht wirklich sinn, zufällige werte zu erhalten. um zu wissen, warum man dadurch performance gewinnen kann, muss man wissen, wie das dbms gruppierungen umsetzt. letzlich werden gruppierungen durch eine sortierung ausgeführt, und zwar über jeden spalte in der GROUP BY klausel. nach der sortierung kann das dbms die gruppenwechsel erkennen und entsprechend handeln. manchmal will man dabei spalten ausgeben, die aber keine veränderung bei der sortierung ergeben würden, sprich die gruppen wären immer noch die gleichen, zum beispiel man gruppiert über einen primary key und gibt noch andere spalte aus der tabelle aus. die gruppierung würde sich nie verändern, das dbms müsste aber trotzdem für jede spalte die sortierung durchführen. deswegen kamen die entwickelr von mysql auf diese idee, diese spalten wegzulassen, aber auch nur diese.

          Ilja

          1. Hi,

            du hättest den link weiter gehen sollen, dort steht: "When using this feature, all rows in each group should have the same values for the columns that are ommitted from the GROUP BY part."

            Ja, *should* have, und zwar in deinem eigenen Interesse als Nutzer - weil du sonst, bei mehreren Werten, wie gesagt einen zufälligen zurück bekommst.

            Dass MySQL es nicht erlauben würde, Spalten auszuwählen, bei denen die nicht der Fall ist, stimmt aber nicht. Es gibt dann nur keine Garantien, welcher Wert ausgewählt wird.

            MfG ChrisB

            --
            “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
            1. moin,

              Ja, *should* have, und zwar in deinem eigenen Interesse als Nutzer - weil du sonst, bei mehreren Werten, wie gesagt einen zufälligen zurück bekommst.

              das sehe ich anders, sie würden eine fehlermeldung ausgeben, sofern sie den könnten, aber dann wäre der performance gewinn wieder dahin. also sind sie in einer zwickmühle und können nur an den jeweiligen benutzer appelieren und genau das tun sie. es macht keinen sinn, zufällige werte auszugeben, sondern im gegenteil stiftet nur ärger und verwirrung oder fällt dir einer ein ?

              Ilja

              1. Hallo Ilja,

                Ja, *should* have, und zwar in deinem eigenen Interesse als Nutzer - weil du sonst, bei mehreren Werten, wie gesagt einen zufälligen zurück bekommst.

                es macht keinen sinn, zufällige werte auszugeben, sondern im gegenteil stiftet nur ärger und verwirrung oder fällt dir einer ein ?

                klar. Futter für Foren wie unseres hier bereitzustellen :-)

                Stell Dir vor, wie viele Fragen es hier dazu schon gab. Wie oft hast Du Dich, habe ich mich über die Frage "it's not a feature, it's a bug" oder umgekehrt ausgelassen.

                Wie oft versuchte der eine oder die andere über dieses Feature korrelierte Subselects (von denen er oder sie noch nie was gehört hatte) zu umgehen, weil in ihren Tests stets der gleiche und dazu noch gewünschte Wert herauskam.

                Freundliche Grüße

                Vinzenz

                1. moin Vinzenz,

                  Stell Dir vor, wie viele Fragen es hier dazu schon gab. Wie oft hast Du Dich, habe ich mich über die Frage "it's not a feature, it's a bug" oder umgekehrt ausgelassen.

                  da lohnt sich eventuell schon fast eine seite hier bei selfhtml zu machen, die diesen bug genau erläutert und man dann nur noch darauf verlinkt, ähnlich wie auch bei den JOINS. das wäre doch was für dich oder ? ;-)

                  Ilja

              2. Hi,

                das sehe ich anders, sie würden eine fehlermeldung ausgeben, sofern sie den könnten, aber dann wäre der performance gewinn wieder dahin.

                Sie können und tun, wenn der Nutzer (bzw. Administrator) das will:
                http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by

                also sind sie in einer zwickmühle und können nur an den jeweiligen benutzer appelieren und genau das tun sie. es macht keinen sinn, zufällige werte auszugeben, sondern im gegenteil stiftet nur ärger und verwirrung oder fällt dir einer ein ?

                Ja, schrieb ich doch - sie appellieren mit dem „should have“ an den Benutzer, sich dieses Verhalten (und den damit ggf. verbundenen Performance-Gewinn) nur dann zu Nutze zu machen, wenn er exakt weiss, was er dann bekommen wird.

                MfG ChrisB

                --
                “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
                1. moin,

                  Sie können und tun, wenn der Nutzer (bzw. Administrator) das will:
                  http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by

                  nein, sie können es nicht. entweder sie gewinnen an performance, dann können sie es nicht prüfen. oder aber sie stellen es nach ansi um, aber dann ist der performance vorteil auch weg, beides geht nicht.

                  Ja, schrieb ich doch - sie appellieren mit dem „should have“ an den Benutzer, sich dieses Verhalten (und den damit ggf. verbundenen Performance-Gewinn) nur dann zu Nutze zu machen, wenn er exakt weiss, was er dann bekommen wird.

                  ich denke, es macht keinen sinn, sich an dem "should" zu hängen. fakt ist, sie können es nicht prüfen. und fakt ist, es macht keinen sinn, sich zufällig werte zurück geben zu lassen, wenn man sich nicht dran hält. würden sie es prüfen können, ohne den performace vorteil wieder zu verlieren, dann würden sie es auch ganz explizit verbieten. da sie dies aber nicht können, wie ich nun mehrfach gesagt habe, sind sie in der zwickmühle.

                  Ilja

                  1. Hallo,

                    Sie können und tun, wenn der Nutzer (bzw. Administrator) das will:
                    http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by

                    ich fänd's lustig, wenn irgendein großer Anbieter im Shared-Hosting-Bereich für alle seine MySQL-Server diese Option ziehen würde :-)

                    Freundliche Grüße

                    Vinzenz

                    1. moin,

                      ich fänd's lustig, wenn irgendein großer Anbieter im Shared-Hosting-Bereich für alle seine MySQL-Server diese Option ziehen würde :-)

                      ich würde es noch besser finden, wenn diese option der standard bei jeder installation wäre. ;-)

                      Ilja

                  2. Hi,

                    Sie können und tun, wenn der Nutzer (bzw. Administrator) das will:
                    http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_only_full_group_by

                    nein, sie können es nicht. entweder sie gewinnen an performance, dann können sie es nicht prüfen. oder aber sie stellen es nach ansi um, aber dann ist der performance vorteil auch weg, beides geht nicht.

                    Irgendwie reden wir hier aneinander vorbei, glaube ich.

                    ich denke, es macht keinen sinn, sich an dem "should" zu hängen. fakt ist, sie können es nicht prüfen. und fakt ist, es macht keinen sinn, sich zufällig werte zurück geben zu lassen, wenn man sich nicht dran hält.

                    Ja - das ist aber dein eigenes Risiko als Nutzer.

                    Wenn du von deinem Datenmodell her ganz sicher *weisst*, dass die Einträge eindeutig sind - dann kannst du dir von denen einen „zufälligen“ zurückgeben lassen, und die DB-Engine kann an der Stelle ein wenig Performance einsparen.

                    würden sie es prüfen können, ohne den performace vorteil wieder zu verlieren, dann würden sie es auch ganz explizit verbieten.

                    Wie gesagt, mit obiger Option kannst du es ganz explizit verbieten *lassen* - dann ist SQL-Standard angesagt diesbezüglich, und die Abfrage von Spalten, die nicht Teil der Gruppierung sind, wird mit einer Fehlermeldung abgewiesen.

                    MfG ChrisB

                    --
                    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
                    1. moin,

                      Irgendwie reden wir hier aneinander vorbei, glaube ich.

                      wir reden davon, dass es bei mysql möglich ist, spalten innerhalb einer gruppierung mit auszugeben, die nicht in der group by klausel stehen, keine aggregatfunktion verwenden und die probleme, die dadurch enstehen, über nichts anderes. wir reden nicht davon, wenn diese einstellung ausgeschaltet ist, zumal das auch nicht jeder ändern kann. wobei Vinzenz einen interessanten aspekt rein gebracht hat, wenn ein großer webhoster das einfach mal tut.

                      und die praxis zeigt, ein kleiner performancegewinn (wenn es den richtig angewandt wird) wiegen einfach nicht die viel größeren nachteile auf. es kann gar nicht im interesse von mysql sein, dass zufällige werte ausgeben werden, sie können es aber auch nicht mit einer fehlermeldung verhindern.

                      Ilja