2016-03-28 25 views
2

平均値をゼロにするためのエレガントなクエリを探しています。mysql - 2フィールドからの平均値(ゼロを無視)

例:私は2つの値を持っている、と期待される結果:

SELECT X(10,20) AS result 
-- expected result: 15 

SELECT X(0,20) AS result 
-- expected result: 20 

SELECT X(10,0) AS result 
-- expected result: 10 

SELECT X(0,0) AS result 
-- expected result: NULL 

これは私の試みです:

(val1+val2)/(2-IF(val1,0,1)-IF(val2,0,1)) 

それを行うには、任意のより良い方法はありますか?

は、いずれかの列を平均化する前に、特別0あるケースを処理するためにあなたに

+1

組み込みのMySQL関数のみを使用する式については、それは得られるほど良いものです。 1つの小さな微調整:分母の値を2から減算するのではなく、分母に加えることができます。 ** '(val1 + val2)/(IF(val1,1,0)+ IF(val2,1,0))' ** – spencer7593

+0

@ spencer7593、それを短くするのは良い考えです! – stramin

+0

私はそれをよりエレガントにするためにとにかく見ることはありません。 'ABS(SIGN()) 'パターンに対する私の好みはおそらく2つの事柄によるものです:** 1)** NULL値の処理。 'ABS(SIGN())'では、0,1またはNULLを返すことができます。 IF()関数を使用すると、私たちは0または1を返すだけです(あなたの仕様に最も適合するものを選んでください)。** 2)**私の初期のホールドオーバー... Oracleは、滑らかなIF()関数を持っています。私の傾向は、DB2、Teradata、およびOracleで利用可能だった表現と関数(実用的なところで)を使うことでした。 (そして、SIGNのトリックは、OracleのDECODEでとても便利でした。) – spencer7593

答えて

2

によると、私はこのようにそれを記述します。変更しよう:

(val1 + val2)/(ABS(SIGN(val1)) + ABS(SIGN(val2))) 

私はOPのexpresssionと同等だと信じて、そのすでにユーザー定義の関数を作成せずに得ることができるほどエレガントに見えます。

(それは一定の「2」から引き算を避けるために、実際には私の個人的な好みだと余分な「1」と「0」の定数。。)

私は三つの引数には、この式を拡張していた場合:

(val1 + val2 + val3)/(ABS(SIGN(val1)) + ABS(SIGN(val2)) + ABS(SIGN(val3))) 

NOTES:

SIGN

のMySQL関数は、数値の "符号" を表す整数値を返します:-101又はNULL

のMySQL ABS機能のでSIGN関数の周り、即ちABS(SIGN(n))リターン01又はNULLなること包装、数の絶対値を返します。 SIGN(ABS(n))は同じものを返します。

引数の1つがNULLの場合、この式はNULLを返します。 OP式と同じように。

私はこれ以上の優雅さはわかりません。しかし、それは私がそれをやる方法です。意図は、SQLを短くする機能を必要とOP例、のように、一度だけval1val2を指定する場合


。 MySQLはネイティブ組み込み関数を提供していないので、ユーザ定義関数を定義(作成)する必要があります。

しかし、我々は、我々は、引数のデータ型とリターン(などなどBIGINTDECIMAL(M,N)DOUBLE、)のデータ型を指定する必要があるだろう、ということでしたし、どちらか私達はそれで行く道ならば、それは可能性を持っています暗黙的なデータ型変換および丸め/不正確さが含まれます。

ユーザー定義関数がない場合、val1val2を式に2回含める必要があります。しかし、私はそれが他の提案された表現のいくつかでそれぞれ4倍または5倍よりも優れていると思います。

1

使用CASEに感謝します。

SELECT CASE 
     WHEN val1 = 0 AND val2 = 0 THEN NULL 
     WHEN val1 = 0 OR val2 = 0 THEN val1 + val2 
     ELSE (val1+val2)/2 
     END AS avg 
1
select case when val1 = 0 and val2= 0 then null 
       when val1 = 0 and val2 ! = 0 then val2 
       when val1 != 0 and val2= 0 then val1 
       else (val1 + val2) /2 
       end avg 

あなたの条件やMySQLバージョン