ORDER BY句

ORDER BY句は、入力として受け取る行の順序を並べ替えます。2つの入力行間の相対順序は、各行についてorder-by句にリストされている式を評価し、各order-by式に関連付けられたsort_specを考慮して結果の値を比較することで決定されます。

構文

orderby_clause ::= ORDER BY 
   expression sort_spec 
   ("," expression sort_spec)*

sort_spec ::= [ASC|DESC] [NULLS (FIRST|LAST)]

セマンティクス

各order-by式のタイプはAnyAtomicである必要がありますか。order-by式で空の順序が返された場合、戻り値として特別な値EMPTYが使用されます。order-by式でjson値を抽出する場合、異なる入力行間でこの式によって抽出される値は、タイプが異なる場合があります(数値、文字列またはブール・タイプ)。

sort_spec: sort_specはソートの方向(昇順または降順)と、特別な値NULL、JNULL、およびEMPTYを特別ではない値と比較する方法を指定します。
  • NULLS LASTが指定されていて、方向がASC/DESCの場合、特別な値はすべての特別ではない値よりも大きい/小さいとみなされます。
  • NULLS FIRSTが指定されていて、方向がASC/DESCの場合、特別な値はすべての特別ではない値よりも小さい/大きいとみなされます。
3つの特別な値そのものの相対順序は固定されています。
  • 方向がASCの場合、順序はEMPTY < JNULL < NULLです
  • それ以外の場合、順序付けは逆になります。
この構文では、sort_specはオプションです。
  • sort_specが指定されない場合、デフォルトはASC順序およびNULLS LASTです。
  • ソート順序のみが指定されている場合、順序がASCの場合はNULLS LASTが使用され、それ以外の場合はNULLS FIRSTが使用されます。
  • ソート順序が指定されていない場合、ASCが使用されます。
前述のルールを考慮し、2つの入力行の間の相対順序は、次のように決定されます。Nをorder-by式の数にし、Vi1、Vi2、... ViNを、行Riでこれらの式を左から右に評価して返されるアトミック値(EMPTYを含む)にします。2つの行Ri、Rjは、Vikが1、2、... Nの各kのVjkと等しい場合に等しいとみなされます。このコンテキストでは、NULLは自身とのみ同等であるとみなされます。それ以外の場合、次のようなVim、Vjmのペアがある場合にはRiはRjよりも小さいとみなされます。
  • mが1であるか、Vikが1、2、...、(m-1)の各kのVjkと等しい
  • VimがVjmと等しくない
  • m番目のsort_specが昇順を指定し、VimがVjmより小さいか、
  • m番目のsort_specが降順を指定し、VimがVjmより大きい

前述のルールでは、2つの値(VikとVjk)の比較は、いずれも特別でない場合、値の比較演算子の項で定義された値の比較演算子のルールに従って実行されます。

VikとVjkに比較可能なタイプがない場合(jsonフィールド別にソートするときに発生する可能性があります)、次のルールが適用されます。
  • 方向がASCの場合、順序付けは数値項目<文字列<ブール値となります。
  • それ以外の場合、順序付けは逆になります。

前述のルールは、ORDER BY句の一般的なセマンティクスを表しています。ただし、現在の実装では、順序付けが実際に行われるときに重要な制限が課されます。具体的には、索引でコンパイル時に必要な順序ですでに行がソートされている場合にのみ、順序付けが可能です。

より正確には、order-by式によってe1、e2、...、eNをORDER BY句に表示されるとおりにします(左から右)。次に、1、2、...、Nの各iについてeiがi番目の索引フィールドの定義と一致し、i番目の索引フィールドが複数キーではない索引(主キー索引または既存の2次索引のいずれか)が存在する必要があります。コンパイル時に、後者の条件によって、order-by式が問合せ実行中に複数のアトミック項目を返さないことが保証されます。さらに、すべてのsort_specに同じ順序付けの方向を指定し、各sort_specについて、特別な値に関して必要な順序が、それらの値を索引でソートする方法と一致する必要があります。現在の実装では、特別な値は常に索引の最後にソートされます。そのため、ソート順序がASCの場合は、すべてのsort_specでNULL LASTを指定する必要があります。また、ソート順序がDESCの場合は、すべてのsort_specでNULLS FIRSTを指定する必要があります。

例6-7 ORDER BY句

SELECT id, lastName 
FROM users 
WHERE age > 30 
ORDER BY id;

前述の例では、年齢が30歳を超えるユーザーのIDと姓を選択し、IDでソートした結果を返します。IDがユーザー表の主キーであるため、この場合はソートが可能です。

例6-8 ORDER BY句

SELECT id, lastName 
FROM users 
WHERE age > 30 
ORDER BY age;

前述の例では、年齢が30歳を超えるユーザーのIDと姓を選択し、年齢でソートした結果を返します。ソートは、age列に2次索引(または、通常は、最初の列がage列である複数列索引)がある場合にのみ可能です。