ストアドプロシージャーを作成するときなど、複数の値から最大値を取得したい場合があります。

しかし、どのようにクエリを書けばいいか分からない。

そういうこともあると思います。

今回は、どのように複数の値から最大値を取ればいいか、2種類の書き方から考えてみることにします。

GREATESTを使う方法

まずは、GREATESTを使う方法を考えてみます。

GREATESTはMySQL、PostgreSQL、Oracleと主要なSQLでは使用することが出来、SQL ServerもSQL Server2022からサポートするようになりました。

例えば以下のような簡単なクエリを考えてみましょう。

DECLARE @str1 as char(3);
DECLARE @str2 as char(3);
DECLARE @str3 as char(3);
DECLARE @str4 as char(3);

SELECT @str1 = '200';
SELECT @str2 = '300';
SELECT @str3 = '500';
SELECT @str4 = '400';

--4つの文字列の最大値を求める
SELECT GREATEST(@str1, @str2, @str3, @str4)

GO

このクエリでは、最初に変数を定義し、その後に変数に値を代入しています。

そして、GREATESTを用いて最大値を求めています。

GREATESTは引数として指定された値から、最大値となるものを抽出するものです。

ですので、このストアドプロシージャーを実行した結果は以下のようになります。

@str3に設定した値である500が最も大きいため、結果が500と返ってきたのが確認できます。

GREATESTが使えない場合の代替案について

では、古いSQL Serverを使っているなどでGREATESTが使えない場合はどうしたらよいでしょうか?

その場合は、GREATESTを使えないため、他の方法を考えるしかありません。

例えば、次のように値をUNION ALLで結合したテーブルを用意し、そのテーブルに関してMAX関数で最大値を取るなどを考えます。

DECLARE @str1 as char(3);
DECLARE @str2 as char(3);
DECLARE @str3 as char(3);
DECLARE @str4 as char(3);

SELECT @str1 = '200';
SELECT @str2 = '300';
SELECT @str3 = '500';
SELECT @str4 = '400';

--4つの文字列の最大値を求める
SELECT MAX(val)
FROM (
  SELECT @str1 AS val
  UNION ALL SELECT @str2
  UNION ALL SELECT @str3
  UNION ALL SELECT @str4
) t

GO

ここではUNION ALLを使っていますが、比較する値の数が多くなければ特にUNIONを使っても問題はないです。

このクエリを実際に実行してみると以下のようになります。

結果のところを見て頂くと分かるように、こちらもきちんと最大値である500を取得して返しています。

このようにGREATESTを使えない時の代替策はあるのですが、行数が増えてやや不便な書き方になるのは覚悟しておいた方がいいでしょう。

まとめ

今回は複数の値から最大値を求める方法としてGREATESTを使う方法と、GREATESTが使えない場合の代替となる方法の2つを紹介しました。

GREATESTは便利な関数なので、使える場合は積極的に使っていくことに越したことはないですが、SQL Serverを使っていて、なおかつ古いシステムであるなどという、GREATESTが使えないケースも存在するかと思います。

GREATESTが使えない場合でも、きちんと代替策を覚えておいて実装できるようになるとSQL Serverを使った古いシステムのメンテナンスを行う時に役に立ちます。

一般的に大規模なシステムはOracleなどを使うことが多く、SQL Serverの知識が不要なことが多いですが、中小規模のシステムの場合は古いSQL Serverを利用して運用されているシステムも0ではありませんので、そんなシステムの改修や保守を行う場合はGREATESTを使えない場合の代替策を使って、同等の処理を実装できるようになっておいた方がいいでしょう。

今回の記事はここまでとなります。
また次の記事でお会いしましょう。