2016-12-27 16 views
1

私はすべてのよくある質問とハウツーによって提案されたOracleデータベースに対して正規の上位Nクエリを持っている:by rownum - それは正しいかどうか?

select ... from (
    select ... from ... order by ... 
) where ronwum <= N 

これは、Oracle 11で完璧に動作し、すなわち、それは内側のSELECTで指定した順番で上位Nレコードを返します。

しかし、それはOracle 12で壊れます。それでも同じトップNレコードが返されますが、シャッフルされる可能性があります。これらのレコードの最終的な順序は非決定的です。

私はGoogleで検索しましたが、関連するディスカッションは見つかりませんでした。他の誰もがそのような選択から常に正しいレコード注文を得ているように見えます。

1つの所見は面白かったですが。

select ... from (
    select ... from ... order by ... 
) where ronwum <= N 
order by rownum 

(;それは内側のSELECTで返さない何かの両方ROWNUMはここにOracleの疑似列への参照である):私は何人かの人々は、外での追加order by rownum句が選択(残念ながら、説明なし)を使用することを見ました

動作しているようです。しかし、オラクルのオプティマイザでは、運が正解であるか本当に正しい解決策であるかは決して確信できません。

質問がありますか:order by rownum保証が正しい場合はこの場合もそうでないのですが、なぜですか?私と私の同僚はそれについて合意に至ることができませんでした。

P.S.私はトップNのレコードを選択する他の方法を知っています。 row_number分析関数と、Oracle 12で導入されたfetch first節を使用しています。私はまた、outer selectで同じorder by ...を繰り返すことができることを認識しています。質問はorder by rownumについてのみです - それは正しいかどうかです。

+3

によってRN < = N 順選択しないと、外側の参照は内側のクエリのものではなく外側のクエリのrownumを参照します。 –

+1

これを行う適切な方法は、サブクエリで行ったのと同じ外部式の式で並べ替えることです。 Oracle 11以前であっても、順序が内部問合せから外部問合せに保存されたという事実は実装上の事故であり、SQL標準では保証されていません。 – mathguy

答えて

-1

内側のクエリと外側のクエリは、異なる順序をとる可能性があり、結果としてローウの順序が異なる場合もあります。 rownumはすでに注文されているので、上位Nレコードを取得する場合は、内部クエリーにrownumのエイリアスを作成して外部クエリーに使用するのが最善です。

...]を選択しますから( 選択ROWNUMのRNの... ...から)ここで、私はあなたが内部で別の何かに `rownum`の名前を変更する必要があると思うRN

+1

注文する前にrownumが割り当てられているので、これは動作しません。このクエリはN個の完全にランダムな行を与えます。 クエリの書き換えは問題のポイントではありませんでした。 – Alexey

関連する問題