Verwenden von 'rand ()' mit 'haben'

9

Ich habe eine Tabelle, die eine Liste von Datensätzen enthält. Für jede Iteration muss eine zufällige Menge von diesen ausgewählt werden, beginnend mit einem bestimmten Offset. Jede Reihe hat eine Chance, ausgewählt zu werden (so werden z. B. neue oder nicht oft gepflückte Reihen mehr gepflückt).

Allerdings funktioniert something nicht, was zur Folge hat, dass Zeilen zurückgegeben werden, die eine Bedingung nicht erfüllen, indem sie ein aliased rand() verwenden.

Ich versuche, die folgende Abfrage zu verwenden:

%Vor%

Dabei ist :offset ein vorbereiteter Anweisungsparameter und ist die letzte gescannte ID in der letzten Iteration für diesen Benutzer.

Auf einer Tabelle, die wie folgt erstellt wurde (was die relevante Teilmenge der Tabelle ist):

%Vor%

Wo ist die Wahrscheinlichkeit ein Wert zwischen 0 und 1 in der Tabelle records . Dies gibt jedoch Zeilen zurück, bei denen die Bedingung nicht erfüllt ist. Ich habe dies mit der folgenden Abfrage überprüft:

%Vor%

Einige zurückgegebene Zeilen sind:

%Vor%

Wenn ich die zweite Abfrage wie folgt umfasse, funktioniert sie wie erwartet und gibt nur Zeilen zurück, in denen rolledChance tatsächlich niedriger ist als probability :

%Vor% Was fehlt mir? Werden die probability und rolledChance anders verwendet als ich im Vergleich gedacht habe? Wird die rand() jedes Mal ausgewertet, wenn der Alias ​​in derselben Abfrage verwendet wird?

Version Ausgabe: mysql Ver 15.1 Distrib 10.0.28-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2 , läuft auf Debian Jessie.

    
Erik S 12.06.2017, 09:32
quelle

1 Antwort

2

Ich denke, das Problem ist, dass HAVING nach GROUP BY angewendet wird, aber immer noch vor der SELECT-Phase. Ich verstehe, dass es verwirrend ist, weil die HAVING-Klausel eine Spalte aus der SELECT-Anweisung referenziert, aber ich denke, es führt im Grunde nur was in der SELECT-Anweisung ist zweimal aus - einmal für das Haben und dann wieder für das SELECT.

Siehe z. B. diese Antwort .

Beachten Sie, dass dies besonders verwirrend ist, weil wenn Sie auf einen Spaltennamen verweisen, der nicht in der SELECT-Anweisung in einer HAVING-Klausel enthalten ist, wird ein Fehler ausgegeben.

ZB diese Geige

Aber gemäß der obigen Fidel lässt es Sie immer noch basierend auf dem Ergebnis einer Funktion filtern, die nicht in der Ausgabe erscheint. Kurz gesagt, die HAVING-Klausel macht immer noch, was Sie wollen, aber Sie können nicht beide nach einem zufälligen Wert filtern und ihn gleichzeitig anzeigen, indem Sie diesen Ansatz verwenden. Wenn Sie dies tun müssen, müssen Sie eine Unterabfrage verwenden, um den Wert zuerst zu korrigieren, dann kann die äußere Abfrage darauf filtern und anzeigen.

Um es klar zu stellen, ist es wahrscheinlich sinnvoll, RAND () nur in der having-Klausel zu verwenden, nicht im SQL-Teil. Obwohl ich die Frage habe, warum es tut, anstatt zu versuchen, das Problem spezifisch zu lösen.

    
Jon Kloske 26.06.2017, 01:02
quelle

Tags und Links