Ich benötige eine Aggregatfunktion, die MySQL nicht bietet.
Ich möchte, dass es in MySQLs SQL-Version ist (dh nicht in C).
Wie mache ich das? Ich bleibe beim Erstellen einer Aggregatfunktion - die Dokumente scheinen nicht zu erwähnen, wie dies gemacht wird.
Beispiele für die gewünschte Verwendung einer product
Funktion:
mysql> select product(col) as a from `table`;
+------+
| a |
+------+
| 144 |
+------+
1 row in set (0.00 sec)
mysql> select col, product(col) as a from `table` group by col;
+-----+------+
| col | a |
+-----+------+
| 6 | 36 |
| 4 | 4 |
+-----+------+
2 rows in set (0.01 sec)
Ich weiß nicht, ob es eine Möglichkeit gibt, eine neue Aggregatfunktion zu definieren, nicht ohne mit dem MySQL-Quellcode herumzuspielen.
Wenn Ihre Zahlen jedoch alle positiv sind, können Sie sich durchaus aus der arithmetischen Identität ableiten:
die Sie verwenden können, um
EXP(SUM(LOG(x)))
zu berechnenPRODUCT(x)
. Test in SQL-Fiddle :Wenn die Daten Nullen haben können, wird es etwas komplizierter:
Getestet bei SQL-Fiddle
Für andere DBMS, die keine automatische Konvertierung von Booleschen Werten in Ganzzahlen durch MySQL haben, ist die
sollte ersetzt werden durch:
Speziell für Oracle sind einige weitere Änderungen erforderlich, ohne die Logik der Antwort zu ändern, nur weil Oracle in einigen Bereichen nicht dem strengen ANSI-Standard folgt. Getestet bei SQL-Fiddle-2
quelle
product
sollte nur ein Beispiel von mehreren sein.PRODUCT(..., 0, ...) = 0
, wollen wir dasEXP(SUM(..., f(0), ...)) = 0
für einigef
, die wir wählen, aber um dies zu erfüllen, brauchen wir dasSUM(..., f(0), ...) = LOG(0)
- wieder vereitelt durch dasselbe Problem wie log (0) ) ist nicht definiert. Wir müssen auf andere Weise prüfen, ob Null vorhanden ist, zMIN(ABS(a)) = 0
. Also hätten wirSELECT CASE WHEN MIN(ABS(a)) = 0 THEN 0 ELSE EXP(SUM(LOG(a))) END AS product
. Ist das die Art von Dingen, an die du gedacht hast?Um das Fischen zu lernen, habe ich erfolgreich ein "Hallo Welt!" Kompiliert und installiert. UDF (benutzerdefinierte Funktion) für MySQL finden Sie hier . Die Datei hello_world.so (nach Einhaltung
gcc -shared -o hello_world.so -I /usr/include/mysql hello_world.c
) sollte in / usr / lib / mysql / plugins / mit 755 Berechtigungen auf Ubuntu-Linux-Systemen gespeichert werden. ["-I / usr / include / mysql" ist der Pfad zu den MySQL-Header-Dateien. Ich habe festgestellt, dass mein Code ohne diesen Parameter nicht kompiliert werden kann, aber YMMV.]Das Programm druckt nur die Zeichenfolge "Hallo Welt!" für jeden Datensatz im resultierenden Datensatz einer Abfrage, aber das ist alles, was es tun soll. Ich werde versuchen, in den nächsten Tagen eine kleine Aggregatfunktion zu schreiben. Es gibt ein Beispiel für eine Aggregatfunktion, die die durchschnittlichen Kosten einer Gruppe von Preis- und Mengenaufzeichnungen berechnet. Die SMALL-Funktion sollte sich am Ende nicht so sehr von dieser Funktion unterscheiden.
Hoffe das hilft.
quelle