• ベストアンサー
  • 暇なときにでも

テーブル参照について

お世話になります。 AテーブルとBテーブルを比較し、Aテーブルにしかないデータ一覧を表示するSQL文を作成しました。 SELECT * FROM Aテーブル WHERE NOT EXISTS(SELECT * FROM Bテーブル WHERE CODE=Aテーブル.CODE AND NAME=Bテーブル.NAME) 下記の場合はどのように記述すればいいのでしょうか? 検索結果はAテーブルに存在しているが、BテーブルまたはCテーブルには存在していないデータ。 以上よろしくお願いいたします。

共感・応援の気持ちを伝えよう!

  • 回答数3
  • 閲覧数78
  • ありがとう数1

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

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

>検索結果はAテーブルに存在しているが、BテーブルまたはCテーブルには存在していないデータ。 というのは、 ・BとCのどちらかに存在していれば検索対象外 ・BとCの両方に存在していれば検索対象外 の2つの意味に取れますよね。 前者なら SELECT * FROM テーブルA WHERE (NOT EXISTS(SELECT * FROM Bテーブル WHERE Bテーブル.CODE=Aテーブル.CODE AND Bテーブル.NAME=Aテーブル.NAME) AND NOT EXISTS(SELECT * FROM Cテーブル WHERE Cテーブル.CODE=Aテーブル.CODE AND Cテーブル.NAME=Aテーブル.NAME)) 後者なら SELECT * FROM テーブルA WHERE (NOT EXISTS(SELECT * FROM Bテーブル WHERE Bテーブル.CODE=Aテーブル.CODE AND Bテーブル.NAME=Aテーブル.NAME) OR NOT EXISTS(SELECT * FROM Cテーブル WHERE Cテーブル.CODE=Aテーブル.CODE AND Cテーブル.NAME=Aテーブル.NAME)) でしょうか。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • 複数のPKを持つテーブル同士の結合について

    以下のような2つのPKを持つテーブル同士で、お互いに存在しないPKのデータを抽出するときのSQLを教えて下さい。 以下のデータの場合、テーブルAではCODE_1がAAAAAのデータ、テーブルBではCODE_1がCCCCCのデータのことを指します。 [テーブルA] CODE_1 CODE_2 ----- --- AAAAA 123 BBBBB 123 [テーブルB] CODE_1 CODE_2 ----- --- BBBBB 123 CCCCC 123 PKがCODE_1だけの場合は、 select distinct テーブルA.CODE_1 from テーブルA,テーブルB where テーブルA.CODE_1 not in ( select テーブルA.CODE_1 from テーブルA,テーブルB where テーブルA.CODE_1 = テーブルB.CODE_1) で、AAAAAが抽出できるとこまでは分かったんですが、複数のPKになったらいきなり分からなくなってしまいました。 どうかよろしくお願いします。

  • Oracle8での外部結合

    現在、oracle8.1.7で開発しています。 T1,T2,T3の3つのテーブルがあります。 T1のデータで、T3のテーブルにまだデータが存在しないものを検索しています。 それは既にできました。 次に、条件として、  (1)T1のA,B,Cと一致し、かつFLGが5または9  (2)T1のA,B,Cと一致するデータがない。 という2点を追加しました。 しかし、以下のようにFLGが1となっているものまで検索してしまいます。   <T1>        <T2>      <T3> A:あいうえお     A:あいうえお    データ無し B:bbb        B:bbb C:ccc        C:ccc             FLG:1   ===SQL文============================================================== SELECT A,DT1,DT2 FROM T1 WHERE A LIKE 'あ%' ---追加部分---- AND ( EXISTS (SELECT A FROM T2 WHERE A=T1.A AND B=T1.B AND C=T1.C AND FLG IN (5,9)) OR NOT EXISTS (SELECT A FROM T2 WHERE A=T1.A AND B=T1.B AND C=T1.C ) ) ----ここまで---- AND NOT EXISTS (SELECT * FROM T3 WHERE KATAMEI='あ' AND NO=1) どこがいけないのでしょうか? よろしくお願いしますm(_ _)m

  • EXSIST述語を使った副問合わせについて

    SELECT HINMOKU_NAME FROM HINMOKU WHERE HINMOKU_CODE IN (SELECT HINMOKU_CODE FROM URIAGE WHERE URIAGE_DATE = '2004-11-10'); 上記をSQL文をEXISTS述語を使って書き換えると エラーが出てしまい、うまく書き換えがすることが できません。下記にエラーがでるSQL文を記載いたします。 SELECT HINMOKU_NAME FROM HINMOKU WHERE EXISTS (SELECT HINMOKU_CODE FROM URIAGE WHERE URIAGE_DATE ='2004-11-10' WHERE HINMOKU.HINMOKU_CODE=URIAGE.HINMOKU_CODE); 上記SQL文についてどこに問題があるのか、ご教授お願い致します。

その他の回答 (2)

  • 回答No.2
  • nda23
  • ベストアンサー率55% (773/1384)

仮にCODEがNULL不許可だとします。 SELECT A.* FROM Aテーブル A LEFT JOIN Bテーブル B ON A.CODE=B.CODE LEFT JOIN Cテーブル C ON A.CODE=C.CODE WHRE B.CODE IS NULL OR C.CODE IS NULL 最後のWHERE句は「Bに無いか、Cに無い」です。 もし、「B、Cともに無い」ならば条件式をAND結合 にするか、サブクエリを使う下記の書式があります。 SELECT X.* FROM (SELECT A.* FROM Aテーブル A LEFT JOIN Bテーブル B ON A.CODE=B.CODE WHERE B.CODE IS NULL) X LEFT JOIN Cテーブル C ON X.CODE=C.CODE WHERE C.CODE IS NULL サブクエリを使う方が速度が速いはずです。特に 元のデータが多く、対象データが少ない場合には 効果が大きくなります。これはCテーブルと結合 させる時点で、レコードが絞り込まれているから です。 上記はANSI形式なので、他のDBシステムでも 使えるSQL文です。(Oracle固有の式は無い) 但し、バージョンによりANSI形式が使えないことが あります。バージョンを記載するとよいでしょう。

共感・感謝の気持ちを伝えよう!

  • 回答No.1

SELECT * FROM Aテーブル MINUS (SELECT * FROM Bテーブル UNION SELECT * FROM Cテーブル )

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • MySQLのUPDATE文でサブクエリ

    MySQLのUPDATE文でサブクエリの使い方について教えて下さい。 MySQLのUPDATE文でサブクエリを使うと「#1093 - You can't specify target table 'exam' for update in FROM clause 」というエラーになってしまいます。 「あるテーブルに対してデータを追加・更新する場合、同じテーブルをサブクエリーに使えない」 「サブクエリー内のFrom句はテンポラリテーブルとして扱うことが可能」 ということはわかりましたが、これに従いSQL文を変更してもうまくいきません。 どのようにSQL文を作ったら良いか教えていただければと思います。 環境 PHP:5.1.6 MySQL:5.0.77 ------具体的なSQL文--------------------------------------- テーブル名:sample カラム名:date(DATETIME型),name,flag 上記テーブルに対して、 1.社員(列名:nameのsuzuki)の最新出勤日(列名:date)のflagを1にする 2.社員(列名:nameのsuzuki)の最新出勤日以外(列名:date)のflagを2にする という処理をしたいと思います。 まず、SELECT文を作ってみました。 1.最新出勤日データを抽出 SELECT * FROM sample WHERE (date= (select max(date) from sample)) and name='sizili' 2.最新出勤日以外のデータを抽出 SELECT * FROM sample WHERE not (date= (SELECT max(date) FROM sample)) and name='suzuki' これをUPDATE文に変更すると、 #1093 - You can't specify target table 'exam' for update in FROM clause というエラーになります。 上記をUPDATE文に変更 1.最新出勤日データを抽出 UPDATE sample SET flag=1 WHERE (date= (select max(date) from sample)) and name='sizili' 2.最新出勤日以外のデータを抽出 UPDATE sample SET flag=2 WHERE not (date= (SELECT max(date) FROM sample)) and name='suzuki' エラー文を検索したところ下記のような情報を見つけることができました。 「仕事SPOT」 MySQLでサブクエリ(エラー#1093を回避する方法) http://wsjp.blogspot.com/2009/12/mysql1093.html 「あるテーブルに対してデータを追加・更新する場合、同じテーブルをサブクエリーに使えない」 「サブクエリー内のFrom句はテンポラリテーブルとして扱うことが可能」 と記載されています。 このページに掲載してあるように変更を加えてみました。 1.最新出勤日データを抽出 UPDATE sample SET flag=1 WHERE (date= (select max(date) as test_max from sample)) as text_tb and name='sizili' 2.最新出勤日以外のデータを抽出 UPDATE sample SET flag=2 WHERE not (date= (SELECT max(date) as test_max FROM sample)) as test_tb and name='suzuki' これでもエラーになってしまい、うまくいきません。

    • ベストアンサー
    • PHP
  • FROM テーブル 名前 ?

    SQLについての質問です. select a.name, b.id from テーブルA a テーブルB b where... というSQLのfromのあとはどういう意味なのでしょうか? テーブルAと同じ型のaを作る という意味なのでしょうか??

  • インラインビューにおける他テーブルの別名参照ができない

    Oracle9iで開発をしています。 インラインビューを使ったSQLで行き詰ってしまいました。 抽出条件として会社テーブルの設立日が12ヶ月前からシステム日付まで、 その該当テーブルのID = 社員テーブルのIDとなる名称を取り出す。 上記に該当する社員テーブルの種類 = 商品テーブルの種類となる名称を取り出す。 となるようにSQLを考えると、 SELECT T1.NAME, T2.NAME FROM 会社テーブル C, (SELECT * FROM 社員テーブル E WHERE C.ID = E.ID) T1, (SELECT * FROM 商品テーブル A WHERE T1.KIND = A.KIND)T2, WHERE C.DATE BETWEEN add_month(sysdate,-12) AND sysdate のような感じになりまして、実行すると"C"."ID":無効な識別子ですと 表示されました。 インラインビューの中ではC、T1のように外部の別名を参照することは できないのでしょうか? できない場合の対策方法なども教えてください。

  • 別テーブルを参照し、その内容を別のテーブルに書き込む

    2つのテーブルに存在しているデータを参照し、 取得したデータの結果を3つ目のテーブルに保存する処理をしているのですが // USERのUNIQUEとGAMEのGAME_NOはプライマリーキー select RATE from USER where UNIQUE = xxx select POINT from GAME where GAME_NO = yyy insert into HISTORY set COIN = RATE * POINT 今は一つの保存に対して3つのSQL文を使わなければいけないのですが、 うまいことこの3つのSQL文を一つか二つにつなげるということは出来ないものでしょうか?

    • ベストアンサー
    • MySQL
  • SQLite C/C++ でのテーブル数の取得

    よろしくお願いします。  テーブル名「TB1332」の有無を確認するSQL 文をこのようにしました select count(*) from sqlite_master where type='table' and name='TB1332'; PupSQLite でのcount(*)の値 当該テーブルが存在する場合 1 当該テーブルが存在しない場合 0 このように正しい結果が得られます。 しかし、Visul Studio 2010 C++ で下記のコードを実行しますと、result の値は、テーブルの有無に関係なく、常に0となります。 int result = sqlite3_exec(pDb, "select count(*) from sqlite_master where type='table' and name='TB1332';", NULL, NULL, &err); C/C++ で該当する、テーブル数を取得するコードの書き方を教えていただけないでしょうか。 環境 C/C++ Visual Studio 2010 Proffesional SQLite3 PupSQLite https://www.eonet.ne.jp/~pup/software.html

  • SELECTのスピード

    SELECTのスピードでどの方法が 検索スピードが速いのか教えてもらいたいのですが Aのテーブル DENNO CODE Bのテーブル CODE NAME Aのテーブルを主にAのCODEでBのテーブルを参照したい時 (1) SELECT A.DENNO,A.CODE, (SELECT B.NAME from B where A.CODE=B.CODE) AS NAME from A (2) SELECT A.DENNO,A.CODE,B.NAME FROM A LEFT JOIN B ON A.CODE=B.CODE (3) SELECT A.DENNO,A.CODE,B.NAME FROM A , B WHERE A.CODE=B.CODE(+)

  • 同じテーブルでのUNION

    テーブルtableである列aのデータが1,2,3,4,5,6,7,8,9と 入っていたとします。 このテーブルを1,2,5,3,4,6,7,8,9という順番で SELECTしたい場合はどのようにすればよろしいでしょうか? select a from table where a IN (1,2) union select a from table where a = 5 union select a from table where a NOT IN (1,2,5) としてみたのですが1,2,3,4,5,6,7,8,9と表示されてしまいます。 宜しくお願いいたします。

  • SQL : たしかに DELETE したの?

    ありがちな処理かと思いまして質問させていただきます。 SQLで DELETE を行う際、WHERE で絞り込んだ対象行がなくても、  「エラーは返ってこない」 ということですが、NOT FOUND判定はするのでしょうか。 ごく単純に、削除しようとしたデータが実際にあったのかを確認したいのです。 やろうとしている処理は、次のようなものです。 DELETE FROM a_tbl WHERE NOT EXISTS (SELECT row1 FROM b_tbl WHERE row1 = 'input_data' ) AND NOT EXISTS (SELECT row1 FROM c_tbl WHERE row1 = 'input_data' ); ようするに、他のテーブルに、すでにない行であることが前提で、 a_tbl から DELETE したことを確認したいのです。 Pro*C内で実行するのですが、一般に同じだと思います。 キホンのキかもしれませんが、よろしくお教えください。

  • oracle 最新日付との比較

    いま、同一商品番号の最新日付を利用した条件が うまく作れず悩みながら色々試していますが、 うまくいきません。 やりたいことは、 1,AテーブルとBテーブルの 商品番号が同じ場合は除外します。 2,残されたデータから次はCテーブルの中にある 同一商品番号で、最新の日付が当月の場合はデータを残す。 つまり、前月以前のデータは除外となります。 1まではできています。 Select * from aテーブル where not exists (select 'X' from bテーブル where a.商品番号 = b.商品番号) この先上記sqlにつなげてmax関数くくった最新日付と システム日付を年月のみで比較する等試みましたが、 求めた結果になりません。 上記sqlでビューを作成してといったことは、 今回やらずに一つのsqlのみでできないかと 試行錯誤です。 よきアドバイスございましたら、 宜しくお願い致します。

  • Oracle SQL DELETE文のレスポンス

    いつもお世話になっております。 この度は、手前のSQL文において DELETE文のレスポンスが上がらずに難儀しています。 現在DELETE処理はバッチにて行っています。 最初にSELECTにて抽出を行ったものをバックアップにとり、 次は同様の条件でDELETE文で処理しています。 この際に、SELECTでは1秒程度で済んだ処理が、 DELETE文ではレスポンスが返ってこないという状況です。 何がまずいのか、どう工夫すればいいのか 色々変えてみましたがレスポンスは改善されません。 SQLと条件は以下です。 【SQL文】 SELECT 複数の項目 FROM TABLEA A WHERE NOT Exists(SELECT 'X' FROM TABLEB B WHERE A.ITEMNO = B.ITEMNO) AND NOT Exists(SELECT 'X' FROM TABLEC C WHERE A.ITEMNO = C.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < C.REPYMD) AND NOT Exists (SELECT 'X' FROM TABLEA2 A2 WHERE A.ITEMNO = A2.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < to_char(A2.CREATEDATE,'YYYYMMDD')) AND NOT Exists(SELECT 'X' FROM TABLEC C WHERE A.ITEMNO != C.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < to_char(A.CREATEDATE,'YYYYMMDD')) 上記のSELECT文の後に処理されるDELETE文は 「SELECT 複数の項目 FROM TABLEA A」 ⇒ DELETE FROM TABLEA A としたもので、 条件は全てSELECT文と同様のものを使用しています。 ◆条件を言葉で明記すると以下のようになります。 1.Bテーブルに存在するものは削除対象外とする 2.AテーブルのアイテムIDとCテーブルのアイテムIDは一致する。   AテーブルのCREATEDATEとCテーブルのREPYMDのいずれかが3ヶ月以内のアイテムは   削除対象外とする 3.AテーブルもしくはCテーブルにしか存在しない場合は、各日付が3ヶ月以内のアイテムは   削除対象外とする 以上のようになっています。 どなたかアドバイスをいただければ幸いです。 宜しくお願い致します。