Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Spaß mit MySQL ;-)

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von akretschmer, 27 Februar 2014.

  1. akretschmer

    akretschmer Datenbank-Guru

    Code:
    mysql> select * from demo;
    +------+------+
    | c  | val  |
    +------+------+
    | a  |  10 |
    | b  |  10 |
    | a  |  20 |
    | c  |  30 |
    +------+------+
    4 rows in set (0.00 sec)
    
    mysql> select c, max(val) from (select * from demo order by c asc) bla;
    +------+----------+
    | c  | max(val) |
    +------+----------+
    | a  |  30 |
    +------+----------+
    1 row in set (0.01 sec)
    
    mysql> select c, max(val) from (select * from demo order by c desc) bla;
    +------+----------+
    | c  | max(val) |
    +------+----------+
    | c  |  30 |
    +------+----------+
    1 row in set (0.01 sec)
    
    Lach und weg...
     
  2. ukulele

    ukulele Datenbank-Guru

    Naja das ist schon nachvollziehbar. Auch wenn es die SQL Syntax verletzt, eigentlich nichts anderes als:
    Code:
    SELECT    max(val),
            (    SELECT    TOP 1 t.c
                FROM    demo t
                WHERE    t.val = demo.val
                ORDER BY t.c ASC )
    FROM    demo
    Natürlich ist es scheisse wenn man sagen wir einen GROUP BY machen will und vergisst ihn anzugeben. Andererseits ist es reproduzierbar und damit nur eine art Hack der SQL Spezifikation um schnell mal eben "Beispieldaten" von c zu bekommen.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    Das Problem ist komplexer.

    MySQL erlaubt das weglassen von GROUP BY. Klarer Verstoß gegen die SQL-Spec. In meinem Beispiel habe ich das Subselect mit einem ORDER BY gemacht, um zu zeigen, daß unterschiedliche Reihenfolge unterschiedliche Resultate bringt. Wenn ich das ORDER BY weglasse steht es der DB frei, die Daten in beliebiger Reihenfolge zu liefern. Die Reihenfolge der Daten in der Tabelle ist ja nicht definiert, und die physische Reihenfolge kann sich durch UPDATE eines Datensatzes auch ändern. Auch kann durch Optimierungen in kommenden Versionen es dazu kommen, daß die Reihenfolge sich ändert (Siehe PG mit synchroniserten parallen Scans, Details dazu auf Nachfrage). Das innere Select kann auch komplexer sein oder ein ORDER BY RAND haben, betrachte das innere Select einfach mal als 'Blackbox'.

    Die Folge ist also: ich muß damit rechnen, bei jedem Aufruf ein unterschiedliches Resultat zu bekommen. Toll!
     
  4. ukulele

    ukulele Datenbank-Guru

    Das ist bedingt richtig. Natürlich steht es der DB frei, in welcher Reihenfolge sie Ergebnisse ohne ORDER BY liefert. Ich behaupte aber ohne Änderung am Datenbestand wird sie es bei der selben Abfrage immer in der selben Reihenfolge tun. Außerdem geht es hier ja eher darum einen beliebigen Wert zu wählen, manchmal (wenn auch selten) will man genau das erreichen.

    Mir wäre auch eine entsprechende Funktion und ein korrektes GROUP BY als Pflichtangabe lieber (gemäß Spec). Das Verhalten von MySQL ist hier aber "nachvollziehbar", wenn auch nicht Regelkonform.

    ORDER BY rand() wird übrigens die Sortierung nicht verändern denn rand() liefert für jede Spalte den selben Wert zurück und wird nicht für jede Zeile neu erzeugt (das nervt mich wirklich^^).
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Darauf sollte man sich nicht verlassen. In PG ist es so, daß wenn Client a ein select * ohne ORDER BY macht, dann wird die Table sequentiell gelesen. Wenn der z.B. zu 50% fertig ist und Client b macht auch ein select * ohne ORDER BY auf dieselbe Tabelle, dann optimiert PG: Client b bekommt den Stream von a, der ja in der Hälfte ist, mitgeliefert. Wenn a fertig ist, bekommt b den 'vorderen' Teil der Tabelle. Ist eine Optimierung seit 8.2 oder 8.3 oder so, weiß nicht mehr genau. a bekommt die Daten also in physische Reihenfolge, b bekommt den hinteren Teil zuerst und dann den vorderen Teil - also in unterschiedlicher Sortierung

    Fazit: ohne Änderung der Daten bekommen 2 Clients dieselben Daten in unterschiedlicher Reihenfolge. Kannst Du Dir sicher sein, daß MySQL in der nächsten Version nicht auch diese Optimierung einbaut?


    Code:
    mysql> select c, max(val) from (select * from demo order by rand()) bla;
    +------+----------+
    | c  | max(val) |
    +------+----------+
    | b  |  30 |
    +------+----------+
    1 row in set (0.01 sec)
    
    mysql> select c, max(val) from (select * from demo order by rand()) bla;
    +------+----------+
    | c  | max(val) |
    +------+----------+
    | a  |  30 |
    +------+----------+
    1 row in set (0.01 sec)
    
    mysql> select c, max(val) from (select * from demo order by rand()) bla;
    +------+----------+
    | c  | max(val) |
    +------+----------+
    | b  |  30 |
    +------+----------+
    1 row in set (0.00 sec)
    
    
    Wie gesagt, betrachte das innere Select als Blackbox. Oder als VIEW, oder als eine Funktion, die Du nicht kennst, die Du nur nutzt.

    Ich find das einfach nur FAIL.
     
  6. Hony%

    Hony% Datenbank-Guru

    Und ich behaupte. dass eine Menge keine Liste ist. Selbst wenn deine Aussage empirisch belegbar ist widerspricht sie der Definition.

    Code:
    SELECT *, random() AS r
    FROM [table]
    ORDER BY r
    Das funktioniert in SQLite, PostgreSQL und sogar MySQL.
     
  7. ukulele

    ukulele Datenbank-Guru

    Letzteres will ich nicht in Frage stellen aber das Ergebnis ist (wenn auch mit Einschränkungen), vorhersehbar.

    MSSQL:

    Code:
    SELECT    rand(),
            pk
    FROM    tabelle
    Ich hab jetzt mal angenommen das ist überall so.
     
  8. Hony%

    Hony% Datenbank-Guru

    http://msdn.microsoft.com/de-de/library/ms177610.aspx
    Bei MS-SQL musst du tatsächlich die Funktion mit sich ändernden Werten füttern. Da arbeitet also kein echter Zufallsgenerator.
     
  9. ukulele

    ukulele Datenbank-Guru

    Jo extrem unpraktisch, ist mir auch schon aufgefallen. Da ist newid() einfacher als Basis für zufällige Zeichenketten.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden