• ベストアンサー

副照会を簡単に使いまわせますか?

たとえば、次のSQLがあったとして、 select キー1, キー2, sum(金額) (  select A.キー1 , A.キー2 , A.金額   from (select * from ~ where ...) A  union all  select '' , A.キー2 , A.金額   from (select * from ~ where ...) A  union all  select A.キー1 , '' , A.金額   from (select * from ~ where ...) A  union all  select ''   , '' , A.金額   from (select * from ~ where ...) A ) group by キー1, キー2 一番内側の副照会は、 (select * from ~ where ...) A は、4箇所とも同じSQL文で、とても長いのですが 2箇所目以降は、1箇所目と同じSQL文ということで 記述を省けたりするような構文があったりしないでしょうか? そこを、ビューにしろといわれるとその通りなのですが ビューにしたくないです。(プログラムで動的にここの副照会部分を パラメータに応じて作っているので、ビューにするとビューがいくつも できて、きりがない) Oracle9iで、利用しています。

  • Oracle
  • 回答数3
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

SQL99における、共通表式 WITH句。 http://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html が判りやすい。 今回のケースは、CUBEが最適です。 ただし、CUBEを使わなくても、発想の転換で、 select キー1, キー2, sum(金額) from (  select X,decode(X,1,A.キー1,2,null,3,A.キー1,null) キー1,      decode(X,1,A.キー2,2,A.キー2,null) キー2, A.金額   from    (select * from ~ where ...) A,    (select 1 X from dummy union all select 2 from dummy union all     select 3 from dummy union all select 4 from dummy) B ) group by X,キー1, キー2 に書き換え可能です。 CUBEで対応できないような事例であっても、必ずしも同じSQLを複数回書かなければならないとは限りません。 当然、書かざるおえない場合はありますが、創意工夫で解決できることもあります。

kurinkurinkurin
質問者

お礼

ありがとうございます。 WITH句が、まさに捜し求めていたものです。 ただし、今回は、ご指摘の通り、CUBEで行こうと思います。 なるほど、そんな書き換え方もあるんですね。 勉強になりました。

その他の回答 (2)

回答No.2

質問に対しては一時表で実現できると答えられます。 ただ、unionを使用する場合、本当にそれが必要かどうか考えたほうが良いかと思います。 今回は単純で目的がクロス集計のようですから、 SELECT A.キー1, A.キー2, sum(A.金額) FROM (select * from ~ where ...) A GROUP BY CUBE(A.キー1, A.キー2) で済みます。

kurinkurinkurin
質問者

お礼

ご回答ありがとうございます。 CUBE便利そうですね。 試してみたいと思います。 一時表のほうも試してみたいと思います。

回答No.1

SQL99でサポートしているのですが、Oracle9iでは使えないハズです。 でも・・ 同じ問い合わせを複数回実行しているわけで、サブクエリを一撃で決められるような気がしますので、 SQL文がn倍長くて動作の遅いものになるのは防げるように思いますよ。

kurinkurinkurin
質問者

補足

ご回答ありがとうございます。 >>SQL99でサポートしているのですが、Oracle9iでは使えないハズです。 これが、気になります。 なんのことを指しているのか、教えていただけませんでしょうか?

関連するQ&A

  • なぜ構文エラーにならないのでしょうか?

    oracle12cで下記のSQLを実行すると13という結果が返ってきます。 しかし、内側のSQLは構文エラーとなります。 Select sum_qty as "13日の金曜日" From ( Select key,Sum(qty) sum_qty From ( Select 'a' key,1 qty from dual union all Select 'a' key,2 qty from dual union all Select 'b' key,10 qty from dual ) ) なぜ13という結果が返ってくるのか理由を知りたいです。

  • UNION ALLのように順番がありNULLを返す方法

    SQL初心者です。ACCESSデータベースに対するクエリを書いているのですが、 条件を配列として、その配列の順番に応じたSELECT文を書きたいのです。 SELECT * FROM access_db WHERE ID = '条件' UNION ALL SELECT * FROM access_db WHERE ID = '条件' UNION ALL SELECT * FROM access_db WHERE ID = '条件' UNION ALL... といった具合にSQL文を作成しているのですが、これでは見つからない条件がある場合に、行が繰り上がり条件を格納した配列とはずれが生じてしまいます。 見つからなかった場合にNULLまたはそれを表せる何かを抽出結果として組み込むことはできますか? SQL初心者のためUNION ALL程度しか近いものが見つけられなく、困っています。 どなたかよろしくお願いします。

  • テーブル結合について、下記SQLをANSI結合の書き方で表したい。

    テーブル結合について、下記SQLをANSI結合の書き方で表したい。 select * from (select key from A union select key from B union select key from C) X, A,B,C where X.key=A.key(+) and X.key=B.key(+) and X.key=C.key(+) このSQLをANSI結合の記述で書きたいのですが、 (+)での結合文になれておらず試行錯誤しております。 下記のようなのかなとは模索しておりますが、 手元に実行環境がなくわかりません。 また、要所気付く点などありましたら、ご指摘願います。 select A.*, B.*, C.* from (select key from A union select key from B union select key from C) X, LEFT JOIN A ON X.key=A.key LEFT JOIN B ON X.key=B.key LEFT JOIN C ON X.key=C.key

  • UNION ALLでつなげた複数ビューの集計

    お世話になっています。 現在下記のようなSQLを組んでいます。 ビュー1の集計結果 UNION ALL ビュー2の集計結果 UNION ALL ビュー3の集計結果 実行結果 例 年月     人数  金額 201104   3    20000 201105   2    10000 201104   1    5000 GROUP BY句で年月を集計したビューをUNION ALLでつないでいるため、 当然のように同じ年月が何度も出てくるため、テストがしづらくなっています。 やりたいこととしては、さっきの実行結果をさらに年月で集計することを 考えています。 年月     人数  金額 201104   4    25000 201105   2    10000 対策として、下記のように集計したビューをUNION ALLでつないだ結果を さらに集計するSQLを作りました。 SELECT  FROM( ビュー1の集計結果 UNION ALL ビュー2の集計結果 UNION ALL ビュー3の集計結果 ) GROUP BY その結果、下記のエラーが発生しました。 ORA-00935:グループ関数のネスト・レベルが深すぎます。 環境はoracle11gです。 あとは、SQLのFROM句の()の部分をビューとして作成し、 更にそのビューを呼び出して集計するくらいしか思いつかないです。 今回作ろうとしてるのはテスト用のSQLのため、SQL文と実行結果を残したいので、 できればビューやプロシージャーは作らずに、SQLのみで作成したいと考えています。 何か良い方法はありますでしょうか? 宜しくお願い致します。

  • 【初歩】SELECT文で思うような照会結果が得られない

    テーブル MYTABLEに、EMAILとPWというフィールドに、それぞれ、 name@example.jp、x6wvGZb7MZpBwMtQという文字列がINSERTされています。 これに対し、 SELECT * FROM `MYTABLE` WHERE `EMAIL` = 'name@example.jp' AND `PW` = 'x6wvGZb7MZpBwMtQ' を実行しても、レコードが返ってこないのですが、なぜでしょうか。 なお、 SELECT * FROM `MYTABLE` WHERE `EMAIL` = 'name@example.jp' なら1件返ってきますが、 SELECT * FROM `MYTABLE` WHERE `PW` = 'x6wvGZb7MZpBwMtQ' だと返ってきません。 シンプルな話なので、はじめはSQL文を手打ちしていてダメでした。 なので、phpMyAdminのGUIからSQL文を発行してみたら 一字一句同じSQL文が吐き出されましたし、照会結果も同じでした。

    • ベストアンサー
    • MySQL
  • オラクルではできるのにSQLSERVERではサブクエリーで複数キーを指定できない?

    サブクエリーで複数キーを指定したいです。例えば以下のようなSQLですが、 SQL> > select * from テーブルA > where (key1,key2) in (select key1,key2 from テーブルB) このSQLはオラクルでは実行できますが、SQLSERVERでは文法エラーになってしまいます。SQL SERVER ではサブクエリーで複数キーを指定するのは不可能なのでしょうか?

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

  • ユニオンクエリでWHERE句を使うのは不可能でしょうか?

    アクセス2003です。 (select * from Q1) UNION ALL (select * from Q2) UNION ALL (select * from Q3); WHERE (((番号) Like "*001")); としても 「SQLステートメントの後に文字が見つかりました。」 となってしまいます。 「番号」と言うフィールドは Q1、Q2、Q3どのクエリにもあり (select * from Q1) UNION ALL (select * from Q2) UNION ALL (select * from Q3); のみなら正常に動作します。 作成したユニオンクエリで「フィルタの対象」で「*001」と入力したらちゃんと思い通りに動作します。 ユニオンクエリで条件抽出は不可能でしょうか? よろしくお願いします。

  • 副問い合わせで複数の列を返す

    こんにちは、Makotoと申します。 SQLの副問い合わせで質問があるのですが、 現在のSQLは CREATE OR REPLACE VIEW VIWTEST AS SELECT KOMOKU1, KOMOKU2 (SELECT SUM(KOMOKU3) FROM TBL WHERE A = 1 (SELECT SUM(KOMOKU4) FROM TBL WHERE A = 1 (SELECT SUM(KOMOKU5) FROM TBL WHERE A = 1 FROM M_TBL; という感じのSQLなのですが、副問い合わせの所 が見ているテーブルも条件も一緒なので1つにまとめたいのですが、うまくいきません。CURSORという関数があったのですが、VIEWでは使用できませんでした。なにかよい方法はないでしょうか? 開発環境は oracle 9i(AIX) pro*C/C++ でおこなっています。

  • ユニオンクエリの場合は「Like [Forms]![フォーム1]![テキスト0]」とはできないのでしょうか?

    こんにちは。いつもお世話になります。 早速ですが T果物、T野菜、T花の3つテーブルでユニオンクエリを作成しました。 (各テーブルのフィールド名は「名前」です。) SQL文は ************************************************ SELECT 名前.名前, * FROM [select * from T果物 UNION ALL select * from T野菜 UNION ALL select * from T花 ]. AS 名前; ************************************************ です。 次に図1の様にテキストボックスに名前を入力してコマンドボタンを押してクエリを開く為のユーザーフォームを作成しました。 コマンド2を押したときは Private Sub コマンド2_Click() DoCmd.OpenQuery ("ユニオンクエリ") End Sub でユニオンクエリを開く動作を指示してあります。 ここまでなら問題なく作業ができるのですが テキストボックスに入力されている名前を含むものがコマンドボタンを押すと表示されるようにしたいのですが どうもユニオンクエリだとうまくいきません。 ユニオンクエリはデザインビューなら図2、 SQL文なら ************************************************ SELECT 名前.名前, * FROM [select * from T果物 UNION ALL select * from T野菜 UNION ALL select * from T花 ]. AS 名前 WHERE (((名前.名前) Like [Forms]![フォーム1]![テキスト0])); ************************************************ とすると、図3のようなエラーが出てしまいます。 ユニオンクエリではなく、普通のクエリ(選択クエリ?)なら 「Like [Forms]![フォーム1]![テキスト0]」の一文を入れても 問題なく作業できます。 何かアドバイスお願い致します。