• 締切済み

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 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 としなければならないのでしょうか

  • 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を書く際に 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; となるようにするよい方法はありませんか? また、予約語が「強調」されると尚良いです。

  • 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では上手く行きませんでした。 よろしくお願いします。

  • GROUP BY使用時のソートについて

    OracleSqlにて「GROUP BY」使用した日付のデータを取得するSql文を作成したのですが、 「ORDER by」句に「DESC」を付けても降順ソートが行えません。 作成したSql文は以下の通りなのですがなぜ降順ソートが行えないのでしょうか? 「GROUP BY」を使用するとソート出来ないと言うことなのでしょうか? それとも日付型なのでソートが出来ないと言うことなのでしょうか? どなたかご存知の方おりましたらご教授下さい。 ------------------------------------------------- SELECT TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY FROM STOCKTBL WHERE TO_CHAR(RECORDDATE,'YYYY/MM/DD')<='2002/03/07' AND TO_CHAR(RECORDDATE,'YYYY/MM/DD')>='2002/02/22' GROUP BY TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY ORDER by TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY DESC -------------------------------------------------

  • 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 をひっくり返した場合、間違いになるのでしょうか? お分かりの方がいましたら教えてください。 よろしくお願いします。

  • ★年度ごとに情報を一覧表示

    各情報を、年度ごとに表示したいと考えています。 基となる年度の条件指定方法が分かりません。 (????と記述しているところです。) 各サブクエリは、年度ごとに情報がない時もあります。 select ????,1tbl.day ,2tbl.day ,3tbl.day from  (select nen,max(day) from 1tbl  where nen < '2006' and nen > '2001'  group by nen  order by nen desc ) 1tbl,  (select nen,max(day) from 2tbl  where nen < '2006' and nen > '2001'  group by nen  order by nen desc ) 2tbl,  (select nen,max(day) from 3tbl  where nen < '2006' and nen > '2001'  group by nen  order by nen desc ) 3tbl where ???? 各サブクエリの情報 1tbl-------2tbl------3tbl------- nen--day----nen--day----nen--day--- 2005-2005/12/12-2005-2005/12/13--------- ---------2004-2004/11/10-2004-2004/12/30 2002-2002/09/01------------------ 表示 nen--1day-----2day-----3day--- 2006-------------------- 2005-2005/12/12--2005/12/13------- 2004--------2004/11/10--2004/12/30 2003-------------------- 2002-2002/09/01-------------- 2001-------------------- ↑上記のように表示したいと考えています。 この形で取れるSQLの書き方はあるでしょうか。 (2006年や2003年のように、情報が0件のところは取れなくてもいいです。) サブクエリ部分をばらばらでSQL発行すれば済む話なのですが、 一度に取れる方法は無いのか気になりまして。 (年度のみのテーブルはありません。) よろしくお願いします。

  • ORDER BY句を使用しているSQL文に関して質問です。

    ORDER BY句を使用しているSQL文に関して質問です。 SELECT文にてORDER BY句を使用した場合、SELECT結果の件数によってソート順が変わるような事はあるのでしょうか? 事象としては以下の通りです。 以下のCUSTOMERテーブルがあるとします。 |店番|顧客番号|一連番号|一連番号枝番| |MISE|KOKYAKU |ITIREN |IEIRENEDANO | |0001|11111111|00000001|000000000000| |0001|11111111|00000002|000000000000| |0001|11111111|00000003|000000000000| |0001|11111111|00000004|000000000000| |0001|11111111|00000005|000000000000| |0001|11111111|00000005|000000000001| |0001|22222222|00000001|000000000000| |0001|22222222|00000002|000000000000| |0001|22222222|00000003|000000000000| |0001|22222222|00000004|000000000000| |0001|22222222|00000005|000000000000| |0001|22222222|00000006|000000000000| |0001|22222222|00000007|000000000000| |0001|22222222|00000008|000000000000| |0001|22222222|00000009|000000000000| |0001|22222222|00000010|000000000000| |0001|22222222|00000011|000000000000| |0001|22222222|00000012|000000000000| |0001|22222222|00000013|000000000000| |0001|22222222|00000014|000000000000| |0001|22222222|00000014|000000000001| 埋め込みSQLを実行し、上記のテーブルに対し以下の条件でカーソルをオープンしました。 (1)SELECT ITIREN FROM CUSTOMER WHERE MISE = 0001 AND KOKYAKU = 11111111 ORDER BY ITIREN DESC (2)SELECT ITIREN FROM CUSTOMER WHERE MISE = 0001 AND KOKYAKU = 22222222 ORDER BY ITIREN DESC カーソルの1件目をFETCHしたところ、以下のような結果となりました。 (1) |店番|顧客番号|一連番号|一連番号枝番| |MISE|KOKYAKU |ITIREN |IEIRENEDANO | |0001|11111111|00000005|000000000001| (2) |店番|顧客番号|一連番号|一連番号枝番| |MISE|KOKYAKU |ITIREN |IEIRENEDANO | |0001|22222222|00000014|000000000000| 一連番号枝番をORDER BY句のソート条件に追加するか、WHERE句の条件についかすれば事象は解決するのですが、同様のSQLを実行しているのに結果が変わってしまうのがどうしても解せません。 もしご存知の方がいらっしゃいましたら、ご教授頂けると助かります。 テーブルの内容をごちゃごちゃと書いてしまったので、見づらくてすみません。。。 レイアウトがずれてたら更にすみませんm(_ _)m HTMLのタグって使えるんでしょうかね?

  • ROWNUMでUPDATEをしたいのですが・・・。

    SQL初心者です。 以下のようなテーブルがあり、 ESTAB/PATTERN/NUMBER/CD 1/00/ 1/01 1/00/ 3/02 1/00/ 4/04 1/00/ 5/05 7/00/ 1/01 7/00/ 2/03 7/00/ 3/04 7/00/ 4/05 (主キー=ESTAB、PATTERN、NUMBER) SELECT ROWNUM,ESTAB,PATTERN,NUMBER,CD FROM (SELECT ESTAB,PATTERN,NUMBER,CD FROM M_PATTERN WHERE PATTERN='00' AND ESTAB='1' ORDER BY NUMBER) WHERE PATTERN='00' AND ESTAB='1' で検索したところの、ROWNUMでNUMBERを更新したいのですが、 UPDATE M_PATTERN A SET A.NUMBER= (SELECT ROWNUM FROM (SELECT ESTAB,PATTERN,NUMBER FROM M_PATTERN WHERE PATURN='00' AND ESTAB='1' ORDER BY NUMBER) B WHERE A.NUMBER=B.NUMBER AND A.PATTERN=B.PATTERN AND A.ESTAB=B.ESTAB AND B.PATTERN='00' AND B.ESTAB='1') WHERE A.PATTERN='00' AND A.ESTAB='1' としてみたところ、一意制約違反が発生してしまいます。 それとも、このようなUPDATEは無理なんでしょうか?

  • 構成比を求めるSQL文につきまして

    科目別受講時間の構成比をRAITO_TO_REPORT関数を使って求めたいと思っています。 以下ですとWHERE句で利用者を特定しての構成比は求まるのですが、where句を除き例えば全利用者で抽出を行うと当然ですが全体の合計jikanの構成比が求まります。 構成比を個人別にしつつ利用者全員を抽出するSQL文の書き方がわかりません・・・。わかる方どうかお教えてください。 SELECT riyousya, kamoku, sum(jikan), to_char(RATIO_TO_REPORT(sum(jikan)) over() * 100,'90.00') || '%' as kouseihi FROM テーブルA WHERE  riyousya = yamada GROUP BY riyousya,kamoku