こんにちは!kossyです!
今回はSQLのGREATOR関数とLEAST関数を使って、MAXやMINとの挙動の違いを調査してみたいと思います。
GREATESTとLEAST関数
GREATESTとLEAST関数は任意の数の式のリストから最大値もしくは最小値を選択します。 評価される全ての式は共通の型に変換できる必要があり、それが結果の型になります(詳細は10.5を参照してください)。 リストの中のNULL値は無視されます。 全ての式がNULLと評価された場合に限って結果はNULLになります。
GREATESTおよびLEASTはSQL標準に載っていませんが、共通した拡張です。 他のいくつかのデータベースでは、全てがNULLの場合に限定せず、いずれかの引数がNULLである場合にNULLを返すようにしているものもあります
出典: 9.17. 条件式
LEAST関数で「任意の数の式のリスト」をコードで雑に現してみます。
query = <<-SQL.squish SELECT LEAST(created_at, updated_at, hired_at, retired_at) as least_date FROM employees LIMIT 10 SQL
上記のようにQueryを走らせると、式のリストの中で最小の値を求めることができます。
実運用だと、「複数の日程の中で期日が一番近い日付が欲しい時」や、「いくつかの価格の中で最安値が知りたい時」等で使えると思います。
MAX・MIN関数との比較
上記ドキュメントにも記載がありますが、GREATEST(LEAST) と MAX(MIN)関数では受け取る引数が異なります。
# 以下SQLだとエラーになる query = <<-SQL.squish SELECT MIN(created_at, updated_at, hired_at, retired_at) as least_date FROM employees LIMIT 10 SQL ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: function min(timestamp without time zone, timestamp without time zone, date, date)
MAX(MIN)関数は複数のレコードを照会して、最大(最小)のレコードを引いてくる動作をします。このため、複数の引数をMAX(MIN)関数に渡すと例外となるわけです。
query = <<-SQL.squish SELECT MAX(hired_at) as max_date FROM employees SQL
上記のQueryだとemployees(従業員)テーブルの中で、入社日が一番若い日付が取得できます。