質問: ``` select ((ifnull(col1,col2) + ifnull(col2,col1))/2) as heikin from table ``` | col1 | col2 | | --- | --- | | 50 | 60 | | 50 | null | | null | 50 | | null | null | テーブルとしては上記のようなパターンがあり、 2つの値の平均値を求めるsqlを作成したいです。 上から2と3レコード目のような、片方がnullの場合は登録されている50の値を出したいです。 一応一番最初に書いたSQLでもやりたいことが実現できるのですが、 もう少しスッキリした書き方があるんじゃないかと思い質問させていただきました、 もしわかりましたらご教授していただきたいです。
回答: SQLではNULLを含んだ計算はNULLになってしまうので、たしかにゴチャゴチャしていますがそんな感じのクエリになってしまうと思います。 今のままでも良いと思いますが、あえていじるとすれば今のクエリは計算方法が若干トリッキーな感じなので、もうちょっと意図がわかりやすいようこんな感じにしてもよいかもしれません。 ``` SELECT COALESCE((col1+col2)/2, col1, col2) AS heikin FROM table; ``` "col1とcol2の平均か、col1か、col2、 さもなくばnull" という条件がそのまま表れてるのでわかりやすいかも? COALESCE関数はリストのうち最初に見つかったNULLではない値を返す関数で、IFNULLが2つの比較なのに対して3つ以上のリストに対応しています。 そもそもの話をすると、データに null が含まれていることや、カラム同士で計算を行うこと自体、テーブルの設計が適切ではないと考えられます。 col1 および col2 が条件によって必ず null になるような場合は、それぞれのカラムを別テーブルに分ける(正規化)べきですし、複数のデータを入れるために col1, col2, col3, ... と横にいくつもカラムを用意してる場合も別テーブルに1データ1レコードで格納すべきです。