• 締切済み

OracleSqlで『RORNUM』の使い方について

VB6でコーディングをしています DBはOracle7.3です SELECT A.One, A.Two, SUM(A.Three) Three,  FROM A  WHERE ( A.One = '001' AND A.Two = '3')  GROUP BY A.One, A.Two ORDER BY Three DESC  上記のようにAテーブルの項目One,Two,Threeを抽出するSQLで 重複項目One,Twoでグループ化したThreeの合計値の内、上位25件を 取得したいのですが... SELECT *  FROM ( SELECT A.One, A.Two, SUM(A.Three) Three,  FROM A  WHERE ( A.One = '001' AND A.Two = '3')  GROUP BY A.One, A.Two ORDER BY Three DESC ) WHERE ROWNUM <= 25 上記のように記述するとORDER BY句でエラーになります ORDER BY句をWHERE ROWNUMの下に記述するとSQLはとおりますが 条件が変わってしまいます。 抽出条件でマージ、降順ソートしたものに対して上位n件の取得をするには どうすれば良いのでしょうか?

みんなの回答

  • misoka
  • ベストアンサー率35% (56/160)
回答No.4

うーん、必ず1回のSELECT文で、25位まで取得しなくてはいけないんですか? msystemさんもおっしゃっていますが、大抵はカーソルをつくって、25回ループさせて取得すると思います... VB6ってことは、ミドルウェアはoo4oでしょうか? oo4oならPL/SQLブロックをDBに投げて、ParamArray(だったっけ?)で値をもってこれるような気がしました。(これってOracle8の話なのかなぁ? 詳しくはoo4oのドキュメントを参照してください) それか、ダイナセットをつくってループさせるっていうのが、多分いちばん単純で簡単です(こっちだとちょっと効率悪い?)。 # それじゃダメだから、質問しているんでしょうか...?

rukaandkaito
質問者

お礼

プログラムが複数本あるため、このプログラムに関してだけPL/SQLを使用するのは一寸抵抗があります。 でも、貴重なお時間をさいて頂いて申し訳ありませんでした。

全文を見る
すると、全ての回答が全文表示されます。
  • msystem
  • ベストアンサー率42% (79/186)
回答No.3

一応できそうなSQL文がありますが、Oracleの動作保証がないため、VBのほうで上位25位をとることをお勧めします。 下にそのSQLを記述します。 まず、例で書いていただいたSQL文は必ず1行しか返ってこないのが気になりますが取りあえず無視して進めます。 まず、ソート用のテーブルを作成します。A.ThreeはNumber型だとします。 create table x (a number); 何でもいいので1行追加します。 insert into x values(0); commit; この準備ができたところで、以下のSQL文を投げます。 select d.one,d.two,d.three from (select c.one,c.two,c.three,c.r,max(r) m from (select b.one,b.two,b.three,rownum r from (select a.one,a.two,sum(a.three) three from a where (a.one='001' and a.two='3') group by a.one,a.two) b,x where b.three=x.a(+)) c group by c.one,c.two,c.three,c.r) d where r>=m-25 order by r desc; 多分、これで25位までの降順で結果が返ってくるはずです。 解説すると、一番内側のサブクエリが合計を出すクエリです。(質問のあったクエリ。ただし、この文だと1行しか返らない) 2番目のサブクエリで、外部結合させることにより並び替えをしています。それと同時に昇順の番号(r)をつけています。(ただし、これは副作用的に並び替えができているだけで、Oracleの保証はありません。これで昇順に並び代わります) 3番目のクエリで、昇順番号の最大値をとっています。 一番外側のSelect文で大きいほうから25位になるような絞込みと、降順の並び替えをしています。 もう少し、スマートな文もあるでしょうが、あとはご自分でがんばってください。

rukaandkaito
質問者

お礼

とってもややこしいSQLをわざわざ考えて下さってありがとうございました(笑) が、ソートテーブルを作成するやり方は一寸いただけないので、ここは諦めて全件抽出後にVBで25回ループする事にします。

全文を見る
すると、全ての回答が全文表示されます。
  • msystem
  • ベストアンサー率42% (79/186)
回答No.2

この問題はOracle8までだと、相当苦労します。 8i以降だとうまくいくのですが・・・ 特に降順なので難しいと思います。ビューを使うのが手ではないでしょうか?

rukaandkaito
質問者

お礼

御回答ありがとうございました ビューを使うと言う事ですが、毎回抽出条件が変わるため使えません 何か効率の良い手はないものでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
noname#1802
noname#1802
回答No.1

そうですね。複問合わせの中に order by は使えません。 ●回答(?)例 SELECT A.One, A.Two, SUM(A.Three) Three FROM A の A.One の前に順序を発生させ ( i = 1,2,3,4,5,・… ) HAVING で i <= 25 でどうでしょう? 実際SQL文を動かしたわけではないので適当です。 すいません。。

rukaandkaito
質問者

補足

sub queryにorder by句を記述できるのはoracle8以上なんですよね! 御回答いただいたHAVINGの例ですが、順序を発生させるとは? 実際にSQLのコーディングはどのようになるのでしょうか? 順序をとるとなると、やはりrounumを使わなければならないのではないでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • sqlのwhereで指定した条件の前後を取得したい

    テーブル=T) KEY DATA 001 あ 002 い 003 う 004 え 005 お SQL) SELECT DATA FROM T WHERE KEY = 003 ; 上記のSQLでは、「う」のデータしか取得できませんが、 「003」の前後1件、合計3件の「い」「う」「え」を取得する方法を教えて下さい。 ちなみに、 SELECT DATA FROM T WHERE KEY >= 003 AND ROWNUM <= 2 と SELECT * FROM ( SELECT DATA FROM T WHERE KEY < 003 ORDER BY KEY DESC ) WHERE ROWNUM < 1 のUNIONでは上手く行きませんでした。 よろしくお願いします。

  • Oracle8のトップN解析

    質問させていただきます。 Oracle8iの場合、トップN解析ということで select id, name from (select id, name from tmp order by id desc) where rownum <= 3; というSQLを作成してidを前から3つだけ検索できますが、 Oracle8の場合、インラインビューでの[order by]が 無効なので、困っています。 よければ、ほかの方法はないものでしょうか?

  • SQL文のGROUPとORDERの順番

    こんににちは、 得点表(学生番号、科目コード、得点)があります。 得点表から各学生の合計得点を求めて降順に整列する場合の正解は、 SELECT 学生番号,SUM(得点) FROM 得点表 GROUP BY 学生番号 ORDER BY 2 DESC だったのですが、この2はSUM(得点)のことでしょうか? また、 SELECT 学生番号,SUM(得点) FROM 得点表 ORDER BY 2 DESC GROUP BY 学生番号 のようにGROUP と ORDER をひっくり返した場合、間違いになるのでしょうか? お分かりの方がいましたら教えてください。 よろしくお願いします。

  • SQL count 別名を条件に使用

    いつもお世話になっております。 標題についてご教授頂きたく質問させて頂きました。 [SQL} select A, B, count(*) as cnt from product where A=1 and cnt > 2 group by A order by cnt desc とこのようにSQLを記述して実行したのですが、 cnt>2でエラーが出ます。 order by には count の別名を使用できるのですが、 where句やHAVINGでは使えません。 この場合 cont(*)>2 またはcount(項目名)>2 としなければならないのでしょうか

  • SQLの書き方を教えて!

    select name,SUM(kingak) from where date between 150221 and 150320 group by frjpc.trcd のようにSUMで集計を行うSQLを発行する時に,同時にkingak順にsortすることは可能なのでしょうか? select name,SUM(kingak) from where date between 150221 and 150320 group by frjpc.trcd order by SUM(kingak) としたいところですが,これではエラーになりますね。 SQLでは解決できないんでしょうか?

  • SQL 句の評価順

    SQL句の評価順について皆さんの意見をいただけないでしょうか? <ケース1:SELECTが最後> ・FROM ・WHERE ・GROUP ・HAVING ・ORDER ・SELECT <ケース2:SELECTがトップ> ・SELECT ・FROM ・WHERE ・GROUP ・HAVING ・ORDER <ケース3:ORDERの前にSELECT> ・FROM ・WHERE ・GROUP ・HAVING ・SELECT ・ORDER どのケースで評価されますでしょうか? ご教授お願いします。

  • order byで並び変えし最大値の項目の抽出方法ついて

    すみません。 order byで並び変えし最大値の項目のみ一意で抽出したいのですが 、 SELECT * from ta order by no,date1,date2; no | date1 | date2 ----+-------+------- 11 | 2008 | 0501 11 | 2008 | 0502 11 | 2008 | 0502 11 | 2008 | 0503 12 | 2008 | 0501 12 | 2008 | 0502 12 | 2008 | 0503 13 | 2008 | 0501 13 | 2008 | 0502 13 | 2008 | 0503 14 | 2008 | 0501 とあった場合、 no,date1,date2のorder by順番で並び変えし 11 | 2008 | 0503 12 | 2008 | 0503 13 | 2008 | 0503 14 | 2008 | 0501 とno項目に対し一つずつだけ出力したい場合どのようにしたらよいのでしょうか? LIMITとoffsetだと1項目分しか出力されず困っております。 SELECT * from ta where no in (select no from ta group by no limit 1 offset 0) order by no,date1 desc,date2 desc limit 1; 宜しくお願い致します。

  • 秀丸でSQLを書く際に SQLの予約語だけ大文字

    秀丸でSQLを書く際に SQLの予約語だけを、大文字に変換するよい方法は? たとえば select * from table_1 where id=1 order by id desc; と書いて、マクロを起動すると SELECT * FROM talbe_1 WHERE id=1 ORDER BY id DESC; となるようにするよい方法はありませんか? また、予約語が「強調」されると尚良いです。

  • クエリの遅さの原因

    下記のクエリーをそれぞれ試してみたところ、圧倒的に下の方が遅くなってしまいました。 $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id order by B.id desc LIMIT 1, 10 ;",$con); $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id where B.name is not null group by B.area order by B.id desc LIMIT 1, 10 ;",$con); where B.name is not null group by B.area この処理はそれほど負荷が掛かってしまうのでしょうか。 他に良い書き方(方法)がありましたら教えてください。

    • ベストアンサー
    • MySQL
  • SQL文 この部分はなんていうのでしょう?

    SELECT T_テーブル1.フィールド1 FROM T_テーブル1 ORDER BY T_テーブル1.フィールド1; なら、 ”ORDER BY句” SELECT T_テーブル1.フィールド1 FROM T_テーブル1 WHERE (((T_テーブル1.フィールド1)="A")); なら ”WHERE句” と言いますが、 DELETE Table1.* FROM Table1; や UPDATE テーブル1 Set テーブル1.フィールド1 = "い" WHERE (((テーブル1.フィールド1)=”あ")); や DROP Table Table1; の deleteやupdateやdropの部分は何て言うのでしょうか? そのまま、SELECT句DELETE句などというのでしょうか?

このQ&Aのポイント
  • 相談したいこと、トラブルに至った経緯、試したこと、エラーなどを教えてください。
  • パソコンもしくはスマートフォンのOSは何ですか?
  • どのように接続されていますか?関連するソフト・アプリがあれば教えてください。電話回線の種類は何ですか?
回答を見る