• ベストアンサー

集合演算子の実用例

中途でIT企業に入ったものです。 SQLを勉強していますが、UNIONやMINUSという集合演算子を 学習しています。 これは実際の開発業務では、どういったケース(業務の要件?)で 使用されるのでしょうか?。 例えばMINUSだと、「前月で売れたが今月は売れてない商品」を抽出する、 などのケースで使用するのでしょうか。 参考に教えて頂けると助かります。

noname#185813
noname#185813
  • Oracle
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

例1)単純に縦に出力したいときに使う。 select 課名,'予算' as 予実,nvl(予算金額,0) from 課マスタ left outer join 予算マスタ on 課マスタ.課コード = 予算マスタ.課コード union select 課名,'実績' as 予実,nvl(実績金額,0) from 課マスタ left outer join 実績マスタ on 課マスタ.課コード = 予算マスタ.課コード order by 課名,予実 とすると、 1課 予算 10000 1課 実績 8500 2課 予算 20000 2課 実績 0 ・・・ とでる。 例2)例1と違ってどちらか一方にしかないデータをどちらも出したいときに使う。 select 課名,sum(予算金額), sum(実績金額) from ( select 課名,予算金額 as 予算金額,0 as 実績金額 from 予算マスタ union select 課名,0 as 予算金額,実績金額 as 実績金額 from 実績マスタ ) group by 課名 order by 課名 とすると 1課 10000 8500 2課 20000 0   ←実績マスタなし 3課 0 8500 ←予算マスタなし とでる。 例3)今年新規(過去3年間取引のなかった取引先も新規として扱う)で獲得した取引先の数 select count(*) from ( select distinct 取引先コード from 売上マスタ where 年度 = 2012 minus select distinct 取引先コード from 売上マスタ where 年度 = 2011 minus select distinct 取引先コード from 売上マスタ where 年度 = 2010 minus select distinct 取引先コード from 売上マスタ where 年度 = 2009 ) 例4)(これはどっちかというとシステム保守要件ですが。) 何らかの異常があったときに不整合データのチェックに使う select * from Aマスタ_バックアップ minus select * from Aマスタ Aマスタ_バックアップにあってAマスタにないものが出てくるので、 これらを調べたりする。 select * from Aマスタ minus select * from Aマスタ_バックアップ 逆のパターンのデータ。これも調べる。 とか。 例5)Orの代わりにunionを使うと便利なこともたまにある。 select * from table1 where Key1 between 1 and 3 union select * from table1 where Key1 between 6 and 7 union select * from table1 where Key1 between 12 and 18 select * from table1 where Key1 between 1 and 3 or Key1 between 6 and 7 or Key1 between 12 and 18 と書けばしまいなのだが、orを使うとインデックスを使ってくれないことがあるので、 orを使わないselectをunionしたほうが早いことがたまにある。 ★table1が、5000万件あるときなどあくまで例外的な使い方です。 !!!普通は、orを使ったほうがいいです!!! ## SQLはこんな感じだったと思うというレベルで書いています。(うまく動かないかも) ## とりあえず、過去に使った例ですぐに思いついたパターンを挙げてみました。

noname#185813
質問者

お礼

皆様有難うございました、大変参考になりました。

その他の回答 (1)

  • root139
  • ベストアンサー率60% (488/809)
回答No.1

下記のページが参考になるかと。 http://codezine.jp/article/detail/1304 なお、標準SQLで MINUS に該当するのは EXCEPT になります。

関連するQ&A

  • ACCESSのSQL

    最近ACCESSを勉強していて、色々なデータベースに関する参考書を見て勉強しているのですが、ACCESSのSQLで和集合演算(UNION)は分かったのですが、積集合演算、差集合演算についてのSQLが分かりません。ACCESSではINTERSECT(積集合演算)でやるとエラーになってしまうので、この積集合演算、差集合演算について、SQLをご教授願います。

  • ACCESS2000でLike演算子

    ACCESS2000で開発しています。 とあるフォーム(これにはレコードソース:SELECT…を記述しています) をDocmd.Openで開く時にWhereConditionを設定しています。 このWhereConditionには、 (A条件) AND (B条件) AND (C条件) AND フィールド名 Like 'XX*' といった内容を書いているのですが、正常に抽出できません。 (A条件) AND (B条件) AND (C条件) までですと抽出できるのですが、Like演算子を使った条件を加えると 0件になってしまいます。 どこが悪いのか全くわかりません。 ちなみに全てのSQL文をクエリのSQLにコピーすると成功します。 ご存知の方、よろしくお願いします。

  • SQL文について(ANDとORの論理演算について)

    下記の質問についてご教授お願い致します [設問] 国語と数学の試験を実施し、2教科の成績は氏名とともに、得点表に記録されている。 1教科は平均点以上で、残りの1教科は平均点未満の生徒氏名を表から抽出するSQLはどれか。 A:国語の点数が国語の平均点以上 B:数学の点数が数学の平均点以上 とするときに、SQL文は SELECT 生徒氏名 FROM 得点 WHERE (A OR B) AND NOT (A AND B) となります。 このときに、 WHERE (A OR B) AND NOT (A AND B) ここの論理演算を理解することが難しいです。 論理演算を分解すると A OR B 国語または数学が平均点以上であるケース NOT (A AND B) 国語と数学の両方が平均点以上であるケース となり、この両者をANDで取ると 1教科は平均点以上で、残りの1教科は平均点未満になることになります。 この論理演算でどうしてもこのような結果を引き出すことができません。 お手数ですがご教授お願いいたします。

  • スパイラル開発とアジャイル開発の違いって

    色々、読みあさっても、今一つ腹落ちしません。 スパイラル開発とアジャイル開発の明確な違いって何でしょうか。 又、どういう場合に何が適してるのでしょうか。 社内の業務システムをスクラッチで開発を進めようかとしています。 業務作業者のメンバーの知識が乏しく、又、経験も浅い為、社内の要件が中々、抽出できない為、ウォーターフォール型以外にしようかと思った次第です。 かといって、プロトタイプのような時間的余裕もありません。

  • SQLで部分的にGROUP BYしたいとき

    はじめまして。 SQLで部分的にGROUP BYで集計したいのですが、 どうもしっくりくるSQLがかけません。 多分CASEあたりを使うと綺麗で高速なSQLがかけると思っています。 皆様のお知恵をお借りしたく投稿しました。 具体的には以下のような出納帳データで 出納帳 日付     金額 2012/8/20 1000 2012/8/20 2000 2012/8/21 -1000 2012/8/21 -2000 2012/8/22 3000 2012/8/23 4000 2012/8/24 -3000 2012/8/24 -4000 2012/8/27 5000 ↓集計 日付     金額 2012/8/20 1000 2012/8/20 2000 2012/8/21 -3000(-1000と-2000を集約) 2012/8/22 3000 2012/8/23 4000 2012/8/24 -7000(-3000と-4000を集約) 2012/8/27 5000 というように、マイナスの金額は集約してしまいたいのですが、どのようなSQLが最適でしょうか? とりあえず、UNIONかなと思い、 (SELECT 日付, 金額 FROM 出納帳 WHERE 金額>=0 UNION ALL SELECT 日付, 金額 FROM 出納帳 WHERE 金額<0 GROUP BY 日付 ) ORDER BY 日付 とプラス金額とマイナス金額にわけUNIONしたのですが、 もっと綺麗(高速)にやる方法があるのではないか?と思い投稿いたしました。 なにかヒントございましたら、ご教授ください。 DB環境:Oracle 11g

  • AccessのUNION ALLについて

    よろしくおねがい致します。 最近アクセスを使い始めたものです。あるテーブルとテーブルの和集合を表示したクエリを作成したいのですが、デザインモードで作成することはできますでしょうか?直にSQL文でUNION ALLを使用すればできたのですが、私の他にもAccess初心者が使用するため、なるべくSQL文を直接使わずにデザインモードで作成する必要があります。 ご教授の程よろしくお願いいたします。

  • 時間の抽出条件

    業務で開発中、どうしてもわからなかったので質問させていただきます。 あるテーブルから「データを抽出する日の14時までにできたデータのみを抽出する」というSQLですが、 データを抽出する日→SYSDATEでYYYYMMDDまでを取得する考えです。 このあとの14:00:00という条件をつけるSQLの書き方がわかりません。 このような書き方ではだめでしょうか? SELECT * FROM T_TEST WHERE DATAYMD < TO_CHAR(SYSDATE '14:00:00','YYYYMMDD HH24:MI:SS'); DATAYMDはCHAR型で8バイトで入っています。 よろしくお願いいたします。

  • Luaのビット演算

    Luaの学習をしています。 Luaのビット演算でbit32を使用してみようと思ったのですが、 実行すると以下のエラーが表示されました。 attempt to index global 'bit32' (a nil value) 色々なサイトを参考にrequireをコールしてみたのですが やはりエラーになりました。 -- トライ1 require("bit32") value = bit32.band(0x1234, 0xFF00) -- トライ2 Bit32 = require("bit32") value = Bit32.band(0x1234, 0xFF00) -- トライ1やトライ2実行時のエラー module 'bit32' not found bit32を使用可能にするにはどうすれば良いのでしょうか? 【補足】 OS:Windows 7 SP1(64bit) 開発環境:Lua Development Tools その他:Luaプロジェクトの新規作成ウィザードで、「lua-5.2」を指定しています

  • PLSQLでのSQLの実行に関しての質問

    [環境] db:oracle 11g express edition os:windowsXP 言語:PLSQL [質問] PLSQLを使用したプログラムを作成していたのですが、SQLの文字数がVARCHAR2(32767)で宣言した変数の文字数を超えてしまいエラーとなります。 理由としては、引数で受け取った配列の数分だけUNIONでSQLを結合し、変数に格納しているのですが、配列の量が多いと変数の最大文字列を超えてしまうようです。(ソースイメージは下記に記述) 対応としては、変数を分割し、SQLを実行することや、SQLを組みなおすなどの対応が考えられるのですが、”(1)処理速度の都合上、できれば1度のSQLで実行したい。”、”(2)抽出条件が配列の条件によって、複雑に変わることと、既に稼働しているプログラムの為あまりソースを変更したくない”という理由から検索条件は変えずに、1度のSQLでどうにか実行できないかと考えています。 上記条件をクリアする何か良い方法はありますでしょうか? (もし、1回のSQLで実行は難しいのであれば、最悪配列を使用してSQLを分割して対応しようとは思っています。ただ、他に方法があるのであればそれに越したことはないです。) どなたか良い方法をご存知の方がおりましたら教えていただけないでしょうか? 宜しくお願い致します。 [ソースイメージ] <引数> 配列[100];          <-- 条件が格納された配列 <変数定義部> hensu_union VARCHAR2(32767); <-- 結合したSQLを格納 hensu_where VARCHAR2(1000); <-- SELECTの条件の格納 <プログラム部>  <省略>  .  .  .   FOR i IN 1..配列分 LOOP <-- 配列の数分、UNIONでSQLを結合 IF i > 1 THEN hensu_union := hensu_union || 'union '; END IF; hensu_union := hensu_union || 'select A,B,C .... from マスタA、マスタB WHERE ' || hensu_where ;  ←ここのUNIONで結合しすぎると最大文字列を超えエラー  END LOOP; . .  省略 . .   OPEN カーソル名 FOR hensu_union ; ←SQLを実行する部分でどうにか1回で済ませたい。                    VARCHAR2を超えるような文字列を格納できたり、                    他の良い方法はあるのか?

  • COBOL言語で開発できますか?

    SQL Server2000のデータ処理をCOBOL言語で開発できますか? 社内システムの開発コスト低減のためシルバー人材を使い安くあげたいと考えています。田舎のシルバー市場ではOPEN系言語を使える人が十分にはみつかりません、それでCOBOLを使って開発できないかと考えました。 すべての業務をCOBOLで開発するのではなくデータを抽出し加工してテキストデータをつくる部分をCOBOLで行えないかと考えています。 (欲を言えばレコードの追加や更新もできればこしたことはないのですが) システムの寿命は約10年と見積もっています