レコードごとに複数の列の値を比較して最大値を求める

 AccessのMax関数やDmax関数は、特定の(1つの)フィールドの中での最大値を求めることはできますが、Excelの関数と違って複数のフィールドの値を比較することができません。そうした場合にいざ最大値を求めようとしても案外厄介ですので、方法をここにメモしておきます。
 別の記事「SQL集合関数を列方向(横方向)に用いて集計を行う」(こちら)に含まれる内容ですが、重要な応用例ですので別の記事として取り上げました。

f:id:accs2014:20161217171241p:plain:right:w600

 例として右のようなテーブルを用います。
 列が3つくらいならIIf関数でなんとか最大値を求められそうですが、5列とか6列になると比較がなかなか面倒になります。


f:id:accs2014:20161217171236p:plain:right:w600

 そこでクエリのデザイン画面です。
 次のような列を設けます。



点数最大: (SELECT Max([点数]) FROM
(SELECT 選手ID,点数A AS 点数 FROM 成績テーブル AS x
UNION ALL SELECT 選手ID,点数B from 成績テーブル AS x
UNION ALL SELECT 選手ID,点数C from 成績テーブル AS x
UNION ALL SELECT 選手ID,点数D from 成績テーブル AS x
UNION ALL SELECT 選手ID,点数E from 成績テーブル AS x)
WHERE x.選手ID=成績テーブル.選手ID)

 簡単に言ってユニオンクエリにより値を縦に並べることでMax関数を適用しています。

※UNION ALL(重複行を除かない)の代わりにUNION(重複行を除く)でも同じ結果となります。ただしMax関数やMin関数の場合はともかく、Avg関数などを用いた場合には正しくない結果となる場合がありますのでUNION ALLで統一しています。


f:id:accs2014:20161217171235p:plain:right:w600

 データシートビューです。