OracleMaster9iOracle入門の勉強している者です。某問題集の問題で、次のような問題がありました。

>EMP表から給与所得(sal列)の高い上位3人の名前(name列)を検索したい。この処理を行っているSELECT文は次のどれか。
A.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp)
WHERE ROWNUM <=3 ORDER BY sal DESC;
B.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp
WHERE ROWNUM <=3 ORDER BY sal DESC);
C.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp
ORDER BY sal DESC) WHERE ROWNUM <=3;
---------------------------
正解は[C]となっていて、その解説によれば、
>インラインビューを使用することで、上(下)位N分析を戻す問合せを実行することが出来ます。この副問合せであらかじめ希望する順序にデータを並べ替えて、主問合せのWHERE句で戻す行をROWNUM擬似列で制限します。・・・以下略
とあり、Cの説明にはなっているものの、なぜA、Bが間違いなのか?つまりなぜWHERE句を副問合せに入れてはいけないのかの説明がない為、すっきりしませんでした。どのように考えれば良いでしょうか?
Oracleに詳しい方どなたかご説明頂ければ幸です。
よろしくお願いします。

回答の条件
  • 1人3回まで
  • 登録:2006/11/14 19:56:24
  • 終了:2006/11/15 00:10:39

ベストアンサー

id:nakamuraaaaa No.2

nakamura回答回数7ベストアンサー獲得回数22006/11/14 21:23:57

ポイント30pt

ポイントはFROM句,WHERE句,ORDER BY句の順番にSQLが解析されるという点です。

※FROM句の中がSQLの場合、さらにFROM句のSQLもFROM句,WHERE句,ORDER BY句の順番で解析されます。

例としてemp表に以下の5件があったとします。この状態を※1とします。

name sal

-------

BLAKE 500

SCOTT 200

KING 1000

ADMS 100

SMITH 700

■(A)の場合

SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp) WHERE ROWNUM <=3 ORDER BY sal DESC;

(1)SELECT name, sal FROM empで※1の順番でデータを抽出します。

(2)次にROWNUM <=3により、上から3行(つまりBLAKE,SCOTT,KING)を抽出します。

(3)最後にORDER BY sal DESCにより(2)の結果を降順にソートするため、結果として以下のようになります。

(A)の結果

name sal

-------

KING 1000

BLAKE 500

SCOTT 200

■(B)の場合

B.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp

WHERE ROWNUM <=3 ORDER BY sal DESC);

(1)ROWNUM <=3により※1の上から3行(BLAKE,SCOTT,KING)を抽出します。

(2)ORDER BY sal DESCにより(1)の結果を降順にソートします。

(B)の結果

name sal

-------

KING 1000

BLAKE 500

SCOTT 200

■(C)の場合

C.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp

ORDER BY sal DESC) WHERE ROWNUM <=3;

(1)ORDER BY sal DESCにより※1をソートします。

(1)の結果

name sal

-------

KING 1000

SMITH 700

BLAKE 500

SCOTT 200

ADMS 100

(2)(1)の結果をROWNUM <=3により上から3行抽出します。

(C)の結果

name sal

-------

KING 1000

SMITH 700

BLAKE 500

以上により(C)が正解となります。

id:takao78ks

判りやすく且つ丁寧な説明ありがとうございました。納得いきました。

2006/11/15 00:10:01

その他の回答(3件)

id:b-wind No.1

b-wind回答回数3344ベストアンサー獲得回数4402006/11/14 20:01:33

ポイント25pt

副問合せ中で rownum を参照してしまうと、ORDER BY で並び替える以前の結果列から最初の3行を選び出すことになってしまいます。

つまり A,B で参照している rownum は意図しているものとは異なるはずです。

id:nakamuraaaaa No.2

nakamura回答回数7ベストアンサー獲得回数22006/11/14 21:23:57ここでベストアンサー

ポイント30pt

ポイントはFROM句,WHERE句,ORDER BY句の順番にSQLが解析されるという点です。

※FROM句の中がSQLの場合、さらにFROM句のSQLもFROM句,WHERE句,ORDER BY句の順番で解析されます。

例としてemp表に以下の5件があったとします。この状態を※1とします。

name sal

-------

BLAKE 500

SCOTT 200

KING 1000

ADMS 100

SMITH 700

■(A)の場合

SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp) WHERE ROWNUM <=3 ORDER BY sal DESC;

(1)SELECT name, sal FROM empで※1の順番でデータを抽出します。

(2)次にROWNUM <=3により、上から3行(つまりBLAKE,SCOTT,KING)を抽出します。

(3)最後にORDER BY sal DESCにより(2)の結果を降順にソートするため、結果として以下のようになります。

(A)の結果

name sal

-------

KING 1000

BLAKE 500

SCOTT 200

■(B)の場合

B.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp

WHERE ROWNUM <=3 ORDER BY sal DESC);

(1)ROWNUM <=3により※1の上から3行(BLAKE,SCOTT,KING)を抽出します。

(2)ORDER BY sal DESCにより(1)の結果を降順にソートします。

(B)の結果

name sal

-------

KING 1000

BLAKE 500

SCOTT 200

■(C)の場合

C.SELECT ROWNUM rank, name, sal FROM (SELECT name, sal FROM emp

ORDER BY sal DESC) WHERE ROWNUM <=3;

(1)ORDER BY sal DESCにより※1をソートします。

(1)の結果

name sal

-------

KING 1000

SMITH 700

BLAKE 500

SCOTT 200

ADMS 100

(2)(1)の結果をROWNUM <=3により上から3行抽出します。

(C)の結果

name sal

-------

KING 1000

SMITH 700

BLAKE 500

以上により(C)が正解となります。

id:takao78ks

判りやすく且つ丁寧な説明ありがとうございました。納得いきました。

2006/11/15 00:10:01
id:kurukuru-neko No.3

kurukuru-neko回答回数1844ベストアンサー獲得回数1552006/11/14 21:19:09

ポイント25pt

ROWNUMの番号はORDER BYする以前に番号

が割り振りされるのます。

A.

SELECT ROWNUM rank, name, sal FROM

(SELECT name, sal FROM emp)

WHERE ROWNUM <=3 ORDER BY sal DESC;

name,selの結果のソート前の最初の3行選んで

salで並び替えたデータを得る。


B.

SELECT ROWNUM rank, name, sal FROM

(SELECT name, sal FROM emp

WHERE ROWNUM <=3 ORDER BY sal DESC);

name,selの結果のソート前の最初の3行選んで

salで並び替えたデータを得る。

※:文法的におかしい気がします

C.

SELECT ROWNUM rank, name, sal FROM

(SELECT name, sal FROM emp ORDER BY sal DESC)

WHERE ROWNUM

name,selをselでソートされた結果よりデータの

最初の3行を得る。

id:andalusia No.4

andalusia回答回数134ベストアンサー獲得回数122006/11/14 22:01:45

ポイント10pt

http://jibun.atmarkit.co.jp/lskill01/rensai/bronzesql09/bronzesq...

上記URLより引用

ROWNUM疑似列は、現在の表内の格納順序どおりに行に連番を振ってしまいます。上位N個、下位N個を取得するには副問い合わせでソートしておくことが必要です。

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません