Oracleの質問です。
10000件以上あるデータから、1000件ずつ結果抽出しようとしています。
where句が
rownum >= 0 and rownum < 1000
では、正しく結果を得られますが、
rownum >= 1000 and rownum < 2000
以降は「レコードが選択されませんでした」になります。
rownum指定なしでは、確実に結果が得られるのですが、考えられる要因はなんでしょうか?
以下のサイトを見ると、
http://www.oikaze.com/~tamada/Products/torque/
> org.apache.torque.adapter.DBOracle というクラスの中に supportNativeLimit と
> getLimitStyle という 二つのメソッドがあります。 この帰り値を false と
> DB.LIMIT_STYLE_NONE に変更します。
という記述があります。
これをPHPで設定するには、
// $db->setOption( 'supportNativeLimit', 'false' ); // これも念のため試しました
$db->setOption( 'supportNativeLimit', false );
$db->setOption( 'getLimitStyle', 'LIMIT_STYLE_NONE' );
というような記述ではNGなのでしょうか?(PEAR:DBを使用しています)
※変数名のすべて小文字も試しましたがNGでした。
投稿した瞬間にキャンセルとなってしまってびっくり(@_@)
本題ですが原因はSQL文にあります。
『SQLの結果より、n件目から10件取得』
http://www.oracle.co.jp/2shin/ora81/16_17.html
最初に選択されたレコードに対応するROWNUMは1になります。これでは11以上20以下という条件に合わず、対象外となって次のレコードを選択します。
rownum >= 0 and rownum < 1000
この場合では最初に選択された条件が1となりますので千件分の抽出が可能ですが、
rownum >= 1000 and rownum < 2000
こちらの場合、、、、最初に選択された条件が1となってしまった段階で、既にどちらの条件にも合致しないという事になってしまいます。
従って、上記ページにありますように、
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name) WHERE rm >=11 and rm<=20;
といったような形でrownumを割り振ってから抽出するというような工夫が必要になります。
投稿した瞬間にキャンセルとなってしまってびっくり(@_@)
本題ですが原因はSQL文にあります。
『SQLの結果より、n件目から10件取得』
http://www.oracle.co.jp/2shin/ora81/16_17.html
最初に選択されたレコードに対応するROWNUMは1になります。これでは11以上20以下という条件に合わず、対象外となって次のレコードを選択します。
rownum >= 0 and rownum < 1000
この場合では最初に選択された条件が1となりますので千件分の抽出が可能ですが、
rownum >= 1000 and rownum < 2000
こちらの場合、、、、最初に選択された条件が1となってしまった段階で、既にどちらの条件にも合致しないという事になってしまいます。
従って、上記ページにありますように、
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name) WHERE rm >=11 and rm<=20;
といったような形でrownumを割り振ってから抽出するというような工夫が必要になります。
★追加コメント★
わかりました。内側のWHEREですでにhoge='foo'済みなので、外側のWHEREには、この条件が不要だったわけですね。
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name WHERE hoge='foo') WHERE rm >=11 and rm<=20;
ということでした。
ありがとうございます。
> 投稿した瞬間にキャンセルとなってしまってびっくり(@_@)
すみませんでしたm(__)m
近しいヒントが見つかった気がしましたので(^^;
すばやいご回答ありがとうございます。
話を簡略化していましたが、実はWHERE句には他にも条件があります。
その場合、上記は、
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name WHERE hoge='foo') WHERE rm >=11 and rm<=20 and hoge='foo';
で良いのでしょうか?
(どうもそのようにやっているつもりなんですがNGです。ひょっとするとeasyミスかも知れませんが)
可能であれば再回答お願いします。
実行している SQL がもう少し無いと判断しにくいですね。
http://www.mitene.or.jp/~rnk/TIPS_ORCL_INSERT.htm#INS4
とりあえず、あげられているページは Java の Torque と言う ORマッパーの説明が書かれています。
設定も Torque 特有のものなので、PHP の場合参考にならないと思います。
★追加コメント★
わかりました。内側のWHEREですでにhoge='foo'済みなので、外側のWHEREには、この条件が不要だったわけですね。
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name WHERE hoge='foo') WHERE rm >=11 and rm<=20;
ということでした。
ありがとうございます。
> 投稿した瞬間にキャンセルとなってしまってびっくり(@_@)
すみませんでしたm(__)m
近しいヒントが見つかった気がしましたので(^^;
すばやいご回答ありがとうございます。
話を簡略化していましたが、実はWHERE句には他にも条件があります。
その場合、上記は、
SELECT column_1,column_2,column_3
FROM (SELECT column_1,column_2,column_3,rownum AS
rm FROM table_name WHERE hoge='foo') WHERE rm >=11 and rm<=20 and hoge='foo';
で良いのでしょうか?
(どうもそのようにやっているつもりなんですがNGです。ひょっとするとeasyミスかも知れませんが)
可能であれば再回答お願いします。