Oracle SQL 関数 : GREATEST,LEAST : 式リストの最大値・最小値

 strRet := GREATEST( expr_list );
 strRet := LEAST( expr_list );

 GREATEST及びLEASTは式リスト expr_list の最大値・最小値を返します。
  expr_list の最初のデータの型が戻されるデータ型となります。
  最初の expr_list が数値である場合、比較の前に残りの引数をそのデータ型に暗黙的に変換します。
  最初の expr_list が数値ではない場合、比較の前に、2番目以降の各exprが最初のexprのデータ型に
  暗黙的に変換されます。
  expr_list のリスト内の最大個数は255個です。


引き数のリストの最初が数値の場合の例を以下に示します。

SQL> SELECT
  2   GREATEST(1, '10', 60, '100.56', 70)
  3  ,LEAST(1, '10', 60, '100.56', 70)
  4  FROM DUAL;

GREATEST(1,'10',60,'100.56',70) LEAST(1,'10',60,'100.56',70)
------------------------------- ----------------------------
                         100.56                            1

4番目の引数の '100.56' は文字列ですが、関数の結果としては数値として戻されることが分かります。

それでは、引き数のリストの最初が文字列の場合の例を以下に示します。

SQL> SELECT
  2   GREATEST('0', 1000, 'cc', 'dd')
  3  ,LEAST   ('0', 1000, 'cc', 'dd')
  4  FROM DUAL;

GREA LE
---- --
dd   0

文字列の処理では、内部的に文字コードが基準となる様です。
関数の結果は左揃えで表示されているので、結果が文字列として返されるのが分かります。

ところでこの GREATESTLEAST 関数の引数のリストは、リテラル(直値)だけではなく、 テーブルの結果のカラムのリストでも可能です。 以下に、引数リストを仮のテーブルからの出力とした例を示します。

SQL> SELECT
  2   GREATEST(VAL1, VAl2, VAL3)
  3  ,LEAST(VAL1, VAl2, VAL3)
  4  FROM (
  5    SELECT
  6       100 AS VAL1
  7      ,200 AS VAL2
  8      ,300 AS VAL3
  9    FROM DUAL
 10  ) TX;

GREATEST(VAL1,VAL2,VAL3) LEAST(VAL1,VAL2,VAL3)
------------------------ ---------------------
                     300                   100


この SQL の FROM句の仮のテーブル「TX」を複数の行を返す様にした例が以下の通りです。

SQL> SELECT
  2   NAME
  3  ,GREATEST(VAL1, VAl2, VAL3)
  4  ,LEAST(VAL1, VAl2, VAL3)
  5  FROM (
  6    SELECT
  7       100 AS VAL1
  8      ,200 AS VAL2
  9      ,300 AS VAL3
 10      ,'1st' AS NAME
 11    FROM DUAL
 12    UNION
 13    SELECT
 14       1000 AS VAL1
 15      ,200  AS VAL2
 16      ,300  AS VAL3
 17      ,'2nd' AS NAME
 18    FROM DUAL
 19  ) TX;

NAME   GREATEST(VAL1,VAL2,VAL3) LEAST(VAL1,VAL2,VAL3)
------ ------------------------ ---------------------
1st                         300                   100
2nd                        1000                   200


この方法を拡張すれば、1個のテーブルの中で性格の類似したデータの中で最大値や最小値を求める場合に 応用ができると思います。

ここで注意点ですが、引数のリストの中に NULL が含まれていると、関数の結果は NULL が返されます。
以下にその例を示します。尚、SET NULL 命令で NULL の場合の表示を変更しています。

SQL> SET NULL '/NULL/'
SQL> SELECT
  2   GREATEST(1, '10', 60, '100.56', NULL)
  3  ,LEAST   (1, '10', NULL, '100.56', 70)
  4  FROM DUAL;

GREATEST(1,'10',60,'100.56',NULL) LEAST(1,'10',NULL,'100.56',70)
--------------------------------- ------------------------------
/NULL/                            /NULL/