ほとんどのデータベースはORDER BY
、サブクエリ内のが次のいずれかであるという事実について非常に明確です。
- 許可されない:たとえばSQL Server、Sybase SQL Anywhere(
TOP
またはで補完されない限りOFFSET .. FETCH
)
- 意味がない:例:PostgreSQL、DB2(
OFFSET .. FETCH
または、で補完されない限りLIMIT
)
DB2 LUWマニュアルの例を次に示します(強調は私のものです)
副選択のORDER BY句は、クエリによって返される行の順序には影響しません。ORDER BY文節は、最も外側の全選択で指定されている場合に返される行の順序にのみ影響します。
PostgreSQLのように、表現は非常に明確です。
並べ替えが選択されていない場合、行は不特定の順序で返されます。その場合の実際の順序は、スキャンおよび結合プランのタイプとディスク上の順序に依存しますが、これに依存することはできません。特定の出力順序は、ソートステップが明示的に選択されている場合にのみ保証されます。
この仕様から、ORDER BY
派生テーブルの句に起因する順序は単なる偶然であり、予想される順序(偶然の例ではほとんどのデータベースで行われます)と偶然一致する可能性がありますが、これに頼るのは賢明ではありません。この。
DB2に関する補足:
特に、DB2にはと呼ばれるあまり知られていない機能ORDER BY ORDER OF <table-designator>
があり、次のように使用できます。
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
この特定のケースでは、派生テーブルの順序を最も外側のSELECTで明示的に再利用できます。
Oracleに関する注意事項:
Oracle では、をOFFSET
使用してページ分割を実装することが長年行われてきましたROWNUM
。これは、派生テーブルを注文した後にのみ合理的に計算できます。
SELECT *
FROM (
SELECT rownum AS rn, t.* -- ROWNUM here depends on the derived table's ordering
FROM (
SELECT * FROM table ORDER BY time DESC
) t
) t
WHERE rn BETWEEN 10 AND 20
少なくともROWNUM
クエリ内に存在する場合、将来のOracleバージョンはこの動作を壊さず、まだはるかに望ましいバージョンに移行していないレガシーOracle SQLをほとんど壊さないことが合理的に期待できます。読み取り可能なSQL標準OFFSET .. FETCH
構文:
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY