2011-08-16 7 views
5

を使用しているとき、私はネット上でのOracleページングクエリを検索し、それらのほとんどは二回クエリをラップするために私に言った:違いROWNUM

SELECT * 
    FROM (SELECT t.*, ROWNUM rn 
      FROM tableName t 
     WHERE ROWNUM < 200) 
WHERE rn > 100 

私のようにそれを入力することができるかどうかだけで不思議:

SELECT *, ROWNUM rn 
    FROM tableName t 
WHERE ROWNUN BETWEEN 100 AND 200 

もう1つもうまくいくようです。これらの2つのクエリの間に(パフォーマンスの)違いはありますか?

+1

あなたはおそらくあなたが必要とする答えを得ていると思いますが、Oracleにとって新しい人はページングクエリに苦労することがよくあります。特に、mysqlはLIMITキーワードを使って簡単にできます。私はこれがオラクルの初心者が間違っている最も一般的なものの1つだと言いたいので、私は最近の記事を書いた - http://betteratoracle.com/posts/18-limiting-query-results-top-n-and- window-queries –

答えて

4

問題は、ROWNUMが生成されているのと同じクエリでフィルタリングしていることです。したがって、サブクエリを作成する必要がある理由は、まずrownumを生成してからフィルタリングを適用する必要があります。 BETWEENがうまく動作する理由はおそらく、エンジンがクエリをどのように処理するかについてのニュアンスですが、一貫して正しい結果が得られない可能性があることには注意が必要です。実際に正しい結果を得ることは、パフォーマンスの問題ではありません。あなたはサブクエリ外より大きく入れて持っている理由

この記事では説明しています。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns009.htm

SELECT * FROM employees 
    WHERE ROWNUM > 1; 

「フェッチされた最初の行が1のROWNUMが割り当てられ、虚偽の状態を作る2行目であることをフェッチされた行が最初の行になり、ROWNUMが1に割り当てられ、条件がfalseになります。その後、すべての行が条件を満たすことができないため、行は返されません。

4

ROWNUMを使用する適切な方法は次のとおりです。

SELECT x.* 
    FROM (SELECT t.*, 
       ROWNUM rn 
      FROM tableName t) AS x 
WHERE x.rn > 100 
    AND x.rn < 200 

BETWEENは含まれており、その2つのクエリは同じロジックではありません。

ROWNUMの詳細については、this link (includes link to Oracle documentationを参照してください。

+0

あなたの答えをありがとう。私の主な関心事は、私の質問では、これらの2つのクエリの間にパフォーマンスの違いがあることです。あなたは、次のリンクを見てみることができます:http://stackoverflow.com/questions/241622/paging-with-oracle これは、クエリを2回折り返します。 – GaryX

+0

@GaryX:私が言ったように、提供されるクエリは同一ではありません。 2番目のクエリはテーブルのすべてを返します。有効なデータを取得するまでは、パフォーマンスが懸念されます。 –

+0

@OMG Ponies、「パフォーマンスは有効なデータを取得するまで懸念事項ではありません」と言いましたか? –