ORDER BY句

ORDER BY句は、結果レコードの順序を指定するときに使用します。

結果レコードをソートするには、属性名または任意式を指定します。

ORDER BYの構文は次のとおりです。
ORDER BY <Attr|Exp> [ASC|DESC] [,<Attr|Exp> [ASC|DESC]]*

ここで、Attr|Expは、属性名または任意式です。属性は、単一割当て属性または複数割当て属性です。

必要に応じて、ソート順を昇順にするか(ASC)、降順にするか(DESC)を指定できます。任意の値の組合せとソート順序を使用できます。方向を指定しない場合は、ASCであると見なされます。

ORDER BY句は次のように動作します。
この例では、Price単一割当て属性が合計されてから、単一割当てWineType属性によりグルーピングされます。結果のレコードは、降順の合計金額でソートされます。
RETURN Results AS
SELECT SUM(Price) AS Total
GROUP BY WineType
ORDER BY Total DESC
25レコードの小規模なセットに対するこの文の結果は次のようになります。
Total      WineType
---------------------------
| 142.34 | Red            |
| 97.97  | White          |
| 52.90  | Chardonnay     |
| 46.98  | Brut           |
| 25.99  | Merlot         |
| 21.99  | Bordeaux       |
| 16.99  | Blanc de Noirs |
| 14.99  | Pinor Noir     |
|        | Zinfandel      |
---------------------------

ZinfandelバケットはPriceがNULL値であるため、末尾にソートされます。ソート順序がASCの場合も、結果ではZinfandelは末尾です。

文字列のソート

文字列値は、Unicodeコード・ポイント順にソートされます。

ジオコードのソート

データ型がgeocodeの場合は、緯度順にソートされ、次に経度順にソートされます。geocodeデータを使用するときに、より意味のあるソート順を確立するには、ある地点からの距離を計算してから、その距離の順にソートします。

式のソート

ORDER BY句では、任意式を使用して結果レコードをソートできます。ORDER BY句の中の式で参照できるのは、ローカル文の属性のみです。ただし、ルックアップ式の場合を除きます。次に単純な文の例を示します。
/* Invalid statement */
DEFINE T1 AS
SELECT ... AS foo

RETURN T2 AS
SELECT ... AS bar
FROM T1
ORDER BY T1.foo  /* not allowed */

/* Valid statement */
DEFINE T1 AS
SELECT ... AS foo

RETURN T2 AS
SELECT ... AS bar
FROM T1
ORDER BY T1[].foo  /* allowed */
加えて、式の中では集計関数を使用できません。次に例を示します。
RETURN T AS
SELECT ... AS bar
FROM T1
ORDER BY SUM(bar) /* not allowed because of SUM aggregation function */

RETURN T AS
SELECT ... AS bar
FROM T1
ORDER BY ABS(bar) /* allowed */

セットによるソート

前述したように、セット(複数割当て属性)によるソートを行う際には、任意ではあるが固定の順序が使用されます。

この例では、Price単一割当て属性が1つのセットに変換されてから、単一割当てWineType属性によりグルーピングされます。結果のレコードは、降順のセットでソートされます。
RETURN Results AS
SELECT SET(Price) AS PriceSet
GROUP BY WineType
ORDER BY PriceSet DESC
25レコードの小規模なセットに対するこの文の結果は次のようになります。
PriceSet                                              WineType
----------------------------------------------------------------------
| { 14.99 }                                         | Pinot Noir     |
| { 12.99, 13.95, 17.5, 18.99, 19.99, 21.99, 9.99 } | Red            |
| { 25.99}                                          | Merlot         |
| { 22.99, 23.99 }                                  | Brut           |
| { 21.99 }                                         | Bordeaux       |
| { 20.99, 32.99, 43.99 }                           | White          |
| { 16.99 }                                         | Blanc de Noirs |
| { 17.95, 34.95 }                                  | Chardonnay     |
|                                                   | Zinfandel      |
----------------------------------------------------------------------

この降順では、ZinfandelバケットはPriceが割り当てられていないため、末尾にソートされます(この場合、空のセットが返されます)。

ORDER BYの一定性

EQLでは、文の結果は問合せごとに変化しないことが保証されます。つまり、次のようになります。

たとえば、ORDER BY句がない文に対して、PAGE(0, 10)を使用する問合せを実行し、PAGE(10, 10)を使用してからPAGE(20, 10)を使用した場合に、更新が何もなければ、同じ結果(不定であるが変動はしない)から、10レコードのグループが順番に返されます。

更新がある場合の例を示します。文でORDER BY Num PAGE(3, 4)が指定されており、最初の問合せでレコード{5, 6, 7, 8}が返されたとします。更新時に、4のレコードが挿入され(指定されたページの前)、6のレコードが削除され(指定されたページ上)、9のレコードが挿入された(指定されたページの後)とします。同じ問合せの結果は、この更新後は{4, 5, 7, 8}になります。この理由は次のとおりです。
  • 4を挿入したことによって、以降の結果が1つずつ下にシフトします。オフセットが3であるため、新しいレコードが結果に含まれます。
  • 6を削除したことによって、以降のすべての結果が1つずつ上にシフトします。
  • 9を挿入しても、この結果に含まれる、またはその前のレコードには影響はありません。

ORDER BYは、RETURN句の結果またはPAGE句の処理にのみ影響することに注意してください。PAGE句を指定していないDEFINEORDER BYを使用しても、何の影響もありません。