SQLでテーブル結合してID毎にRANKの有無を判定する方法

このQ&Aのポイント
  • SQLを使用して、tableA、tableB、tableCを結合し、ID毎にRANKの有無を判定する方法について説明します。
  • 結果として、IDとRANKを表示し、RANKが存在する場合は'○'とその数を、存在しない場合は'×'と0を表示します。
  • 適切なSQLクエリを使用することで、要件を満たす結果を得ることができます。
回答を見る
  • ベストアンサー

SQLでテーブルを結合した結果を取り出し

SQLで以下の様なテーブルがあります。 tableA、tableB、tableCを使って、IDとNUMとRANKを結合し、 ID毎に、 RANKが1つでもあったら、”○”でその数を RANKが1つもなかったら、”×”で0を 取り出したい。 「oracle10g」です。 -- tableA ID,NUM,NAME,・・・・・ 000001,001, 000001,002, 000001,003, 000002,001, 000003,001, 000003,002, -- tableB ID,NUM,RANK 000001,001,A 000001,001,B 000001,001,C 000001,002,A 000001,003,C 000002,001,B 000002,002,B 000003,001,A 000003,002,A 000003,002,C --tableC RANK,NAME A, B, C, 結果として、 ID,RANK,判定,個数 000001,A,○,2 000001,B,○,1 000001,C,○,2 000002,A,×,0 000002,B,○,2 000003,A,○,2 000003,B,×,0 000003,C,○,1 を得たいです。 どのようなSQLにしたらよいか、よろしくお願いします。

  • Oracle
  • 回答数5
  • ありがとう数14

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

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

=============================================== with tableA as ( select '000001' as ID,'001' as NUM,'TEST1' as NAME from dual union all select '000001' as ID,'002' as NUM,'TEST1' as NAME from dual union all select '000001' as ID,'003' as NUM,'TEST1' as NAME from dual union all select '000002' as ID,'001' as NUM,'TEST2' as NAME from dual union all select '000002' as ID,'002' as NUM,'TEST2' as NAME from dual union all select '000003' as ID,'001' as NUM,'TEST3' as NAME from dual union all select '000003' as ID,'002' as NUM,'TEST3' as NAME from dual ), tableB as ( select '000001' as ID,'001' as NUM,'A' as RANK from dual union all select '000001' as ID,'001' as NUM,'B' as RANK from dual union all select '000001' as ID,'001' as NUM,'C' as RANK from dual union all select '000001' as ID,'002' as NUM,'A' as RANK from dual union all select '000001' as ID,'003' as NUM,'C' as RANK from dual union all select '000002' as ID,'001' as NUM,'B' as RANK from dual union all select '000002' as ID,'002' as NUM,'B' as RANK from dual union all select '000003' as ID,'001' as NUM,'A' as RANK from dual union all select '000003' as ID,'002' as NUM,'A' as RANK from dual union all select '000003' as ID,'002' as NUM,'C' as RANK from dual ), tableC as ( select 'A' as RANK,'基A' as NAME from dual union all select 'B' as RANK,'基B' as NAME from dual union all select 'C' as RANK,'基C' as NAME from dual ), IDRANK as ( select A.ID, C.RANK from tableA A, tableC C group by A.ID, C.RANK ) select T.ID, T.RANK, case count(B.ID) when 0 then '×' else '○' end as 判定, count(B.ID) as 個数 from IDRANK T left join tableB B on B.ID = T.ID and B.RANK = T.RANK group by T.ID, T.RANK order by T.ID, T.RANK =============================================== =============================================== ID,RANK,判定,個数 000001,A,○,2 000001,B,○,1 000001,C,○,2 000002,A,×,0 000002,B,○,2 000002,C,×,0 000003,A,○,2 000003,B,×,0 000003,C,○,1 =============================================== 私の環境では上記の結果になります。 (RANKの"D","E"は使用されていないようなので除外しています) 求められている結果と一致しているかと思うのですが・・・

abc999xyz
質問者

お礼

ありがとうございます。 同じ結果となりました。

その他の回答 (4)

回答No.4

with句での仮想データで一致するのなら実テーブルのデータが異なるだけだと思います。 以下の3つのSQL結果を教えてもらえれば原因確認程度はお手伝い出来るかと思います。 select ID,NUM,NAME from tableA select ID,NUM,RANK from tableB select RANK,NAME from tableC

abc999xyz
質問者

お礼

ありがとうございます。 3つのテーブルの結果です。 -- tableA ID,NUM,NAME, 000001,001,TEST1 000001,002,TEST1 000001,003,TEST1 000002,001,TEST2 000002,002,TEST2 000003,001,TEST3 000003,002,TEST3 -- tableB ID,NUM,RANK 000001,001,A 000001,001,B 000001,001,C 000001,002,A 000001,003,C 000002,001,B 000002,002,B 000003,001,A 000003,002,A 000003,002,C --tableC RANK,NAME A,基A B,基B C,基C D,初1 E,初2

回答No.3

========================================================= with tableA as ( select '000001' as ID,'001' as NUM,'' as NAME from dual union all select '000001' as ID,'002' as NUM,'' as NAME from dual union all select '000001' as ID,'003' as NUM,'' as NAME from dual union all select '000002' as ID,'001' as NUM,'' as NAME from dual union all select '000003' as ID,'001' as NUM,'' as NAME from dual union all select '000003' as ID,'002' as NUM,'' as NAME from dual ), tableB as ( select '000001' as ID,'001' as NUM,'A' as RANK from dual union all select '000001' as ID,'001' as NUM,'B' as RANK from dual union all select '000001' as ID,'001' as NUM,'C' as RANK from dual union all select '000001' as ID,'002' as NUM,'A' as RANK from dual union all select '000001' as ID,'003' as NUM,'C' as RANK from dual union all select '000002' as ID,'001' as NUM,'B' as RANK from dual union all select '000002' as ID,'002' as NUM,'B' as RANK from dual union all select '000003' as ID,'001' as NUM,'A' as RANK from dual union all select '000003' as ID,'002' as NUM,'A' as RANK from dual union all select '000003' as ID,'002' as NUM,'C' as RANK from dual ), tableC as ( select 'A' as RANK, '' as NAME from dual union all select 'B' as RANK, '' as NAME from dual union all select 'C' as RANK, '' as NAME from dual ), IDRANK as ( select A.ID, C.RANK from tableA A, tableC C group by A.ID, C.RANK ) select T.ID, T.RANK, case count(B.ID) when 0 then '×' else '○' end as 判定, count(B.ID) as 個数 from IDRANK T left join tableB B on B.ID = T.ID and B.RANK = T.RANK group by T.ID, T.RANK order by T.ID, T.RANK ========================================================= tableA/B/Cをwith句で仮想的に生成し、 私の環境(11gまたは9i)で上記のSQLを実行した結果が以下です。 ========================================================= 000001,A,○,2 000001,B,○,1 000001,C,○,2 000002,A,×,0 000002,B,○,2 000002,C,×,0 000003,A,○,2 000003,B,×,0 000003,C,○,1 ========================================================= 今10g環境がないので10gでは試してませんが、 これでいけないとなるとレコード数が違っているか10gでSQL解釈が異なるとかが考えられるかと思うのですがtableA/B/Cのレコード数は上記のwith句内と一致してるでしょうか?

abc999xyz
質問者

お礼

ありがとうございます。 10g環境で、記載していただいたSQLを実行しました。 同じ結果となりました。

回答No.2

いくつか確認させて下さい。 ・tableA/B/Cの情報は質問の内容だけで間違いないでしょうか? ・見落としてましたがNUMは結合条件に必要ですか?(IDだけで連結してました) ・下記SQL実行結果をコピペしてもらう事は可能ですか? select * from ( select A.ID, C.RANK from tableA A, tableC C group by A.ID, C.RANK ) T left join tableB B on B.ID = T.ID and B.RANK = T.RANK order by T.ID, T.RANK

abc999xyz
質問者

お礼

ありがとうございます。 >tableA/B/Cの情報は質問の内容だけで間違いないでしょうか? tableA/B/Cの情報は質問の内容以外もあります。 住所、電話番号、日付等などもあります。 抜粋ですか以下の通りです。 000001,A,000001,0001 000001,B,000001,0001 000001,C,000001,0001 000001,D,NULL,NULL 000002,A,NULL,NULL 000002,B,000002.0002 000002,C,NULL,NULL という具合です。

回答No.1

with IDRANK as ( select A.ID, C.RANK from tableA A, tableC C group by A.ID, C.RANK ) select T.ID, T.RANK, case count(B.ID) when 0 then '×' else '○' end as 判定, count(B.ID) as 個数 from IDRANK T left join tableB B on B.ID = T.ID and B.RANK = T.RANK group by T.ID, T.RANK order by T.ID, T.RANK こんな感じでしょうか。 10gだったらwith句使えた気がしますが使えなかった場合は select T.ID, T.RANK, case count(B.ID) when 0 then '×' else '○' end as 判定, count(B.ID) as 個数 from ( select A.ID, C.RANK from tableA A, tableC C group by A.ID, C.RANK ) T left join tableB B on B.ID = T.ID and B.RANK = T.RANK group by T.ID, T.RANK order by T.ID, T.RANK これでいけると思います。

abc999xyz
質問者

お礼

ありがとうございます。 確認してみたのですが、 個数が、tableAのID数分となります。 ”000001”の”A”はtableBでは”2”つしかないのに ”3”となります。 ”000002"の”A”はtableBでは存在しないのに ”1”となります。 また、tableBにまったくレコードががないIDの場合、 ”0”ではなく、”1”となります。 よろしくお願いします。

関連するQ&A

  • 3つのテーブルを結ぶSQLの書き方

    お世話になります。 3つのテーブルを結びつけるSQLの書き方がわかりません。ご指導お願いします。 [TableA][ID] [TableB][ID] [TableC][ID] [TableA]と[TableB]をLEFT JOINでつなぐ。 上の結果を[TableA][ID]と[TableC][ID]でInner joinでつなぐ。 つまり・・・ SELECT TableA.ID,TableB.ID FROM TabelA LEFT JOIN TableB→この結果 SELECT TableA.ID,TableB.ID TableC.ID From この結果 INNER JOIN TableC ON TableA.ID = TableC.ID こんな感じのことをやりたいのですが、記述の方法がわかりません。 どなたかお知恵をお貸しください。

  • 複数テーブル検索で同idの部分は結合させたい

    初心者です。 ちょっと伝えずらいのですが、 下記のようなテーブル構造になっています。 ■tableA +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 1 | test1 | aaaaaaaaaa | | 2 | test2 | bbbbbbbbbbbb | +----+-------------------+------------------------------------------+ ■tableB +----+-------------------+------------------------------------------+ | id | name | sex | +----+-------------------+------------------------------------------+ | 1 | taro | men | | 2 | yoko | women | +----+-------------------+------------------------------------------+ ■tableC +----+-------------------+------------------------------------------+ | id | num | order_id | +----+-------------------+------------------------------------------+ | 1 | 33 | 1 | | 2 | 66 | 2 | +----+-------------------+------------------------------------------+ ■tableD +-------------------+------------------------------------------+ | icons | order_id | .+-------------------+------------------------------------------+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 5 | 1 | | 1 | 2 | | 3 | 2 | +-------------------+------------------------------------------+ tableA,B,Cのidを軸にデータを表示したいのですが、 --------------------------------------------------------- tableA.id , body , name , sex , num , order_id FROM tableA , tableB , tableC WHERE tableA.id = tableB.id AND tableA.id = tableC.id ---------------------------------------------------------- で出力できました。 で、tableDのiconsの内容も出力したいのですが、 --------------------------------------------------------- tableA.id , body , name , sex , num , order_id , icons FROM tableA , tableB , tableC WHERE tableA.id = tableB.id AND tableA.id = tableC.id AND tableC.order_id = tableD.order_id ---------------------------------------------------------- でやると、2行しかデータがでないはずなのですが、 6行出力されてしまいます。 たぶん、tableDのデータの持ち方が、 ひとつのidに複数のiconsがある場合は、 行ごとにレコードを分けているためだと思いますが・・・ tableDの行分、6行でているのです。。 なので、期待する結果は、 ちゃんとidの数分だけ出力されて、 同order_idにiconsが複数ある場合は、 行ごとに分かれるのではなく、 ひとつのカラム?にカンマ区切りなどで 入れたいのですがどうしたらよいでしょうか?? ↓期待する結果 ----------------------------------------------------------------------- +----+-------------------+------------------------------------------+ | id | title | body | order_id | icons +----+-------------------+------------------------------------------+ | 1 | test1 | aaaaaaaaaa | 1 |1,2,3,5 | 2 | test2 | bbbbbbbbbbbb | 2 | 1,3 +----+-------------------+------------------------------------------+ ※カンマじゃなくてもいいです わかりづらくて申し訳ありませんが、 ご教授お願いいたします。 MySQL 5.0.90-log ちなみにec-cubeの高度な設定の csvを吐き出す部分で使用しています。

    • ベストアンサー
    • MySQL
  • 2つのテーブルを結合する際にIDを割り当てたい

    PHPでmySQLを作成しています。 現在学習中なのですが、自己解決できない問題が発生したのでどうかお知恵をお貸しください。 --- 同じデータベースにTableAとTableBがあります。 中身は下記のようだとします。 TableA      |  TableB id  name time | name time :   :   :  |  C1   D2 101 A1  B1  |  C2   D2    102 A2  B2  |   :    : 103 A3  B3  |  C20  C20 --- テーブルAのカラムid、name、timeの3カラム、テーブルBはname、timeの2カラムです。 これを --- TableA        TableB id  name time  name time :   :   : 101 A1  B1 102 A2  B2 103 A3  B3 104 C1  D1 105 C2  D2 :   :   : 123 C20  D20 --- とするような方法を教えてください。(TableBはレコードなし) テーブルの結合ではIDが割り当てられず、上手な方法が思いつきません。 どうかご教示のほど、よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • SQL:テーブル結合で該当レコードがない場合

    SELECT TableA.ID,SUM(TableA.量),TableB.金額 FROM TableA,TableB WHERE TableA.ID = TableB.ID GROUP BY TableA.ID,TableA.量,TableB.金額 こんな感じのSQLなんですが TableAをメインテーブルとして ↓のような結果を得るように作り変えれないか考えています ■TableBとの結合レコードあり(金額登録あり) 1,50,1500 ■TableBとの結合レコードあり(金額登録なし) 1,50,(NULLかスペース) 考えているんですが思いつかないのでヒントいただけたらと思います。宜しくお願いします。

  • テーブルの差分をとる結合

    TableAとTableBがあります。構造は同じです。 中身は下記のようだとします。 TableA      TableB ID VALUE     ID VALUE 1 A       3 C 2 B       4 D 3 C        差分結合結果を下記のようにとりたいのです。 1 A 2 B 4 D 良い方法をご存じでしたら、ご教授よろしくお願い致します。

  • 複数表での集計値について

    以下のようなテーブル構造。SQLで 集計値を求めたいのですがCNTの値が tableCの件数を取得してしまいます。 (取得したいのはtableA.ID毎のtableB.ID2の件数) 宜しくお願いします。 ・tableA ------------- ID ------------- ・tableB ------------- ID | ID2 ------------- ・tableC ------------- ID2 | TIME ------------- SELECT tableA.ID ,SUM(tableC.TIME) AS TIME ,COUNT(tableB.ID2) AS CNT FROM tableA,tableB,tableC WHERE tableA.ID = tableB.ID AND tableB.ID2 = tableC.ID2 GROUP BY tableA.ID

    • ベストアンサー
    • MySQL
  • 1つのテーブルから複数のテーブルへのデータ振分け

    MySQLを使用して、tableAというテーブルのデータを tableB,tableC,tableDというテーブルに振り分けたいと思っています。 1日1回、自動的に行いたいと思っています。 たとえば、tableAのテーブル構成が下記のようなもので ================== name sex birth address phone email company ================== name,address,phoneはtableBに name,sex,birthはtableCに name,companyはtableDに分けるというような イメージです。 私の考えでは、下記のようなSQL文をPHPから呼び出して、タスクで 実行させてそれぞれ別のテーブルに振り分けようと思っている のですが、、もっと良いツールや方法があればお教えいただけ ませんでしょうか。 宜しくお願いいたします。 ---------------------------------------------------------------------------------------------------- INSERT INTO tableB (name,address,phone) SELECT tableA.name,tableA.address,tableA.phone FROM tableA AND INSERT INTO tableC (name,sex,birth) SELECT tableA.name,tableA.sex,tableA.birth FROM tableA AND INSERT INTO tableD (name,company) SELECT tableA.name,tableA.company FROM tableA; ----------------------------------------------------------------------------------------------------

  • テーブルを結合

    テーブルの結合に関して質問します。 ネットなどでinner joinを使った複数のテーブル結合が参考として 書いてあったのですが(3つまで), 4つテーブルを結合する事は 出来るのでしょうか? A,B,CテーブルにはID,NAMEがあります。 DテーブルにはA,B,CテーブルのIDがあります。 参考サイトを見て3つのテーブルを結合するSQLが以下になります。 SELECT a.name, b.name, c.name FROM a INNER JOIN (b INNER JOIN c ON b.id = c.id) ON a.id = c.id よろしければアドバイスお願いします。

  • 2つのテーブル結合

    Oracle10g使用しています。 テーブルAとテーブルBを結合させてデータを取得したいと思っています。 [テーブルA] ID name 1 A 2 B 3 C 4 D [テーブルB] ID SEQ VALUE 1 1 111 2 1 222 2 2 333 3 1 444 4 1 555 4 2 666 4 3 777 テーブルAのキーは[ID]、テーブルBのキーは[ID,SEQ]です。 この二つを連結して以下のように出力したいと思っています。 ID SEQ NAME VALUE 1 1 A 111 2 2 B 333 3 1 C 444 4 3 D 777 テーブルBのデータは同じIDのうち最大のSEQのものを取得したいのですが よいSQLが思いつきません。 よい方法があればご教授ください。 よろしくお願いいたします。

  • 3つのテーブルから値を取得する

    お世話になっております。MySQL 4.1.20 phpMyAdmin 2.6.0-pl3 です。 tableCのcityname='BOS'で、f_kubun='B'を出し、tableBのadd_charge='5000'とtableAのa_fare=80000 を合計したいのですが、やり方がまずいのか、件数が多いのか途中で止まります。 まだ、 tableC.f_kubun=tableB.c_kubun もできていない状態です。 テーブル tableA 約40000件 t_code | t_from | t_to | a_fare xx45cc |20070209|20070220| 80000 xx45cc |20070220|20070331| 70000 テーブル tableB 約20000件 t_code | c_kubun | add_charge | xx45cc |A | 0 | xx45cc |B | 5000 | テーブル tableC 約120000件 t_code |cityname |f_kubun|rtng|stop_o| xx45cc |NYC | A | 0 | 1 | xx45cc |BOS | B | 0 | 1 | $cityname='BOS'; $day='20070210'; 欲しい答え85,000 $sql = "select add_charge,a_fare from tableA inner join (tableC inner join tableB on tableC.t_code = tableB.t_code) on tableA.t_code = tableB.t_code where t_from<='$day' and t_to>='$day' and a_fare>0 and cityname='{$cityname}' and rtng='0' and stop_o='1'"; とまってしまうので、あっているかどうかもわからないのですが やはりやり方が悪いのでしょうか? よろしくお願いします。

    • ベストアンサー
    • MySQL