entsprechend Ihrer Anforderung oder MySQL-Version ändern ich es so schreiben würde:
(val1 + val2)/(ABS(SIGN(val1)) + ABS(SIGN(val2)))
Ich glaube, dass an den OP express gleichwertig ist, die bereits sieht ungefähr so elegant aus wie es wird, ohne eine benutzerdefinierte Funktion zu erstellen.
(Es ist wirklich nur meine persönliche Präferenz die Subtraktion von der Konstante „2“ und die zusätzlichen „1“ und „0“ Konstanten zu vermeiden..)
Wenn ich diesen Ausdruck auf drei Argumente zu verlängern:
(val1 + val2 + val3)/(ABS(SIGN(val1)) + ABS(SIGN(val2)) + ABS(SIGN(val3)))
NOTES:
die MySQL SIGN
Funktion einen ganzzahligen Wert darstellt, das "Zeichen" eines numerischen Wert zurück: -1
, 0
, 1
oder NULL
.
Die MySQL ABS
Funktion wird den absoluten Wert einer Zahl zurück, so dass rund um Funktion SIGN Einwickeln, d.h. ABS(SIGN(n))
die Rückkehr 0
, 1
oder NULL
sein wird. SIGN(ABS(n))
würde das gleiche zurückgeben.
Wenn eines der Argumente NULL ist, gibt dieser Ausdruck NULL zurück. Genau wie der OP Ausdruck.
Ich bin mir nicht sicher, dass das eleganter ist. Aber so würde ich es machen.
Wenn die Absicht ist, die SQL kürzer zu machen, zu spezifizieren val1
und val2
nur einmal, wie sie in den OP Beispielen, die eine Funktion benötigen. Da MySQL dafür keine native Built-Funktion bietet, müssten wir eine benutzerdefinierte Funktion definieren (erstellen).
Aber wenn wir das täten, würden wir die Datentypen der Argumente und den Datentyp der Rückkehr (zB BIGINT
, DECIMAL(M,N)
, DOUBLE
, etc.) und wie auch immer wir gehen damit angeben müssen, wird es Potenzial für implizite Datentypkonvertierungen und Rundungen/Ungenauigkeiten.
Ohne eine benutzerdefinierte Funktion müssen val1
und val2
zwei Mal in den Ausdruck einbezogen werden. Aber ich denke, das ist besser als die vier oder fünf Mal in jedem der anderen vorgeschlagenen Ausdrücke.
Für einen Ausdruck, der nur eingebaute MySQL-Funktionen verwendet, ist das ungefähr so gut wie es wird. Eine kleine Verbesserung: Sie könnten die Werte im Nenner hinzufügen, anstatt sie von 2 zu subtrahieren, z. ** '(val1 + val2)/(IF (val1,1,0) + IF (val2,1,0)) ** – spencer7593
@ spencer7593, das ist eine gute Idee, es kürzer zu machen! – stramin
sehe ich sowieso nicht, um es eleganter zu machen. Meine Präferenz für das 'ABS (SIGN())' -Muster ist wahrscheinlich auf zwei Dinge zurückzuführen: ** 1) ** Behandlung von NULL-Werten. Mit 'ABS (SIGN())' können wir 0, 1 oder NULL zurückbekommen. Mit der IF() -Funktion erhalten wir nur eine 0 oder 1 zurück. (Wählen Sie einfach diejenige aus, die Ihrer Spezifikation am besten entspricht.) Und ** 2) ** ein Überbleibsel aus meiner früheren Zeit ... Oracle didn ' t haben eine glatte IF() Funktion. Meine Tendenz war, mit Ausdrücken und Funktionen (wo praktisch) zu gehen, die in DB2, Teradata und Oracle verfügbar waren. (Und der SIGN-Trick war wirklich praktisch in einem Oracle 'DECODE'.) – spencer7593