階層問い合わせに関するSQLの問題

このQ&Aのポイント
  • Oracle 11gの環境で、階層問い合わせに関するSQLの問題が発生しています。
  • 部品テーブルから直下のレコードのみを抽出しようとしていますが、共通の構成を持つ部品群の中に入れると、同じ結果が2回表示されます。
  • サンプルのデータとSQLを用意しましたが、どこに問題があるか教えていただきたいです。
回答を見る
  • ベストアンサー

SQLに関して

環境:Oracle 11g SQLで階層問い合わせに関して教えて下さい。 今、ある部品テーブルに対し、直下のレコードのみを抽出しようとしていますが、ある共通の 構成をA部品群、B部品群の中に入れた場合、なぜか同じ結果が2回表示されてしまいます。 以下にサンプルのデータとSQLを作成しましたので、何がおかしいか教えて頂きたいと思います。 【Aテーブル】 品目番号,親品目番号 A A1,A B,A B1,B ↑ A部品群 C D,C B,C B1,B ↑ B部品群  ※ Bが共通の構成です。 【SQL】 select 品目番号 as 下位品目番号,親品目番号 from A_TABLE where 品目番号 != 'B' AND 親品目番号 = 'B' start with 品目番号 = 'B' connect by prior 品目番号 = 親品目番号 【結果】 下位品目番号,親品目番号 B1,B B1,B 2回表示されてしまいます。 単純に親品目番号=’B’としてしまえば正しく拾えますが、上記のSQLを多様している為、 何が間違っているか教えて頂ければと思います。 初歩的な質問で申し訳ありませんが、教えて下さい。

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

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

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

ANo.1です。 説明の内容に誤解をまねく内容がありましたので訂正します。 >質問に書かれた【Aテーブル】の中身のように、 というのはちょっと違っていて、 start with 品目番号 = 'B' となっているので、 【Aテーブル】 品目番号,親品目番号 B,A B,C の2レコードを拾ってきてそれぞれについて正展開しています。 だから、 start with 親品目番号 = 'B' としたら、 B1,B の1個しか拾ってこないから目的が達成できたと思うけど・・・ (未確認。ひょっとしたらエラーになるかもしれません。  申し訳ないですが今手持ちの試せる環境がないので。)

asamix_000
質問者

お礼

Siegrune様、ありがとうございます。 なんとか目的を達成する事ができました。 ありがとうございました!

その他の回答 (1)

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

> select 品目番号 as 下位品目番号,親品目番号 from A_TABLE > where 品目番号 != 'B' AND 親品目番号 = 'B' > start with 品目番号 = 'B' connect by prior 品目番号 = 親品目番号 で、質問のデータなら、 >2回表示されてしまいます。 というのは当然の結果と思います。 実際の【Aテーブル】の中身が 品目番号,親品目番号 A A1,A B,A B1,B C D,C B,C  ※ Bが共通の構成です。 ともっており、B1,Bが1個しかないのになぜ? と思われるかもしれませんが、 ------------引用------------- Oracleは次のように階層問合せを処理します。 最初に、結合(指定されている場合)が、FROM句で指定されているか、またはWHERE句述語で指定されているかが評価されます。 CONNECT BY条件が評価されます。 残りのWHERE句述語が評価されます ------------引用おわり------------- http://docs.oracle.com/cd/E16338_01/server.112/b56299/queries003.htm より。 とあるように > where 品目番号 != 'B' AND 親品目番号 = 'B' より先に > start with 品目番号 = 'B' connect by prior 品目番号 = 親品目番号 が行われるので、 質問に書かれた【Aテーブル】の中身のように、 B1,Bが2個ある状態で、 > where 品目番号 != 'B' AND 親品目番号 = 'B' が適用され、2個でてきます。

asamix_000
質問者

補足

Siegrune様、ご回答ありがとうございます。 詳細に教えて頂き、本当にありがとうございます。 同様の内容を別HPにも問い合わせしている事をお許し下さい。 ご指摘頂いたように、私のSQLでは2件表示されるのは当然なようですね、、、 なんとかこれをB以下を1回だけ表示させられないかとdistinctを使い表示させましたが、 それでは並び順がぐちゃぐちゃになってしまいます。 B1の下にもB2あるいはB3というデータあった場合でも、正しく B B1 B2 という順序で表示される方法はないでしょうか??? 教えて頂ければ幸いです。 よろしくお願いします。

関連するQ&A

  • SQLを教えて下さい

    SQL文を教えて下さい 以下の2つのテーブルがあります。 TABLE1 --------------- ID,NAME,PRICE --------------- 1,部品A,100 2,部品B,200 3,部品C,300 TABLE2 --------------- ID,NAME,PRICE --------------- 1,部品Aのサブ1,1 1,部品Aのサブ2,2 2,部品Bのサブ1,5 2,部品Bのサブ2,5 --------------- SELECT TABLE1.NAME TABLE2.NAME TABLE1.PRICE TABLE2.PRICE WHERE TABLE1.ID = TABLE2.ID(+) TABLE2.PRICE = (SELECT MAX(?) ?) 期待する結果 ・TABLE1.NAME = 部品Aの場合 --------------- 部品A,部品Aのサブ2,100,2 ・TABLE1.NAME = 部品Bの場合 --------------- 部品B,部品Bのサブ1,200,5 TABLE1.NAME = 部品Cの場合 --------------- 部品C,,300, ・TABLE1のNAMEに、TABLE2のNAMEが関連付く(付かないものもある) ・外部結合とMAX関数を用いたい。 ・TABLE2のPRICEが大きい方を取得(同一の場合は、どちらかを取得)

  • 場合によって条件を変えるSQL

    ORACLE環境下、SQLにて以下のような条件でデータを取得したいです。 AテーブルとBテーブルを結合して、Bテーブルから名称を取得する。 <Aテーブル> id (key) 番号1 番号2 A01  001  n0001 A02  null  n0002 <Bテーブル> code(key) 名前  番号1 番号2 c0001   太郎  001  n0001 c0002   次郎  002  n0002 (1)A.番号が入力されていれば A.番号1=B.番号1 AND A.番号2=B.番号2を条件にする (2)A.番号が入力されていなければ A.番号=B.番号を条件からはずす。 A.番号2=B.番号2 のみで検索する。 <欲しい結果> A01→太郎を取得 A02→次郎を取得 入力されていたら条件に加え、入力されていなかったら 条件から外す、というSQLを教えていただけないでしょうか。 よろしくお願いいたします。

  • SQL、すべての部品を…

    以下のような問い合わせをしたい時のSQL表現について教えていただきたいです。 【テーブル名と属性】 テーブル名(*属性A,属性B)のように示します。 *は主キーです。 部品(*部品番号, 部品名) 供給(*部門番号,*部品番号,*業者番号,単価,数量) 供給は 業者Aが部品Bを部門Cに供給している… ということを表します。     【問い合わせ】 登録されているすべての部品の供給を受けている部門の部門番号の一覧 分かる方、すみませんがアドバイスをいただけないでしょうか。

    • ベストアンサー
    • MySQL
  • SQLでの抽出条件

    SQL初心者です。初歩的な質問だと思いますが、ご教授願います。 以下のような2つのテーブルがあります。 【テーブルA】 グループ 社員番号 A 1 A 2 A 3 B 4 B 5 B 6 C 7 C 8 D 9 D 1 【テーブルB】 社員番号 1 9 テーブルBの社員番号と一致する場合、テーブルAをグループ単位で抽出しないようにしたいです。  ・グループAは社員番号1が一致するため抽出しない。  ・グループDは社員番号1と9が一致するため抽出しない。 【取得結果】 グループ 社員番号 B 4 B 5 B 6 C 7 C 8 説明が分かりづらくて申し訳ありませんが、よろしくお願い致します。

  • SQL

    SQLの初心者です。 次のようなテーブルがあるとします。 項目:A , B , C , D このテーブル合計を求めたいのです。 条件は、 同一テーブルでB=10の時のAの合計とD=10の時のCの合計の合計です。 B=10の時のAの合計は「sql sum(A) from テーブル where B=10」となります。 D=10の時のCの合計は「sql sum(C) from テーブル where D=10」となります。 この2つの合計を求めたいのです。 宜しくお願いします。

    • ベストアンサー
    • MySQL
  • SQLの書き方を教えてください。

    初めまして。sql初心者です。OracleのSQLについて質問があります。 「update Aテーブル set Aテーブル.構成順 = (select Bテーブル.順番 from Bテーブル where Aテーブル.ID = Bテーブル.ID and Aテーブル.種類 = Bテーブル.種類CD)」 こういった内容のSQLって発行できるんでしょうか。 Bテーブル.種類CDの"種類CD"で「コンポーネント"種類CD"を宣言してください」というエラーになります。 書き方が分かりません。。 すいませんが教えていただきたく思います。 よろしくお願いいたします。

  • SQL2000からSQL2005へのレプリケーション

    日々更新されるSQL2000(サーバー2000)上のテーブルA、テーブルB、テーブルCをSQL2005(サーバー2005)上で参照するために、レプリケーションの機能を使って、SQL2000をパブリッシュとしてSQL2005上をサブスクライバとしてプルサブスクリプション(スケジュール実行)でSQL2005上にテーブルA、テーブルB、テーブルCを生成させたいと考えております。 SQL2000側でパブリッシュの設定、2005側からプルサブスクリプションの設定ともに問題無く設定できたのですが、いざ実施すると 下記のエラーが出て実行できませんでした。 お聞きしたい点としてはそもそも上記の方法でのSQL2000から2005へ テーブルコピーが可能なのか? 無理な場合は、他にどの様な方法でスケジュールで任意のテーブルを 2000から2005へコピーするあるか教えていただけますでしょうか? ------------ ユーザー 'HOGEDOMAIN\サーバー2000$' はログインできませんでした。 (ソース: MSSQLServer, エラー番号: 18456) ヘルプの表示: http://help/18456

  • SQLの勉強中の者です。

    SQLの勉強中の者です。 調べてもよく分からなかったので、分かる方、ご教授いただけると嬉しいです。 ●DBテーブル情報  A B C ---------------  1 1 1  1 2 1  1 2 2 ●取得条件 「A」=1 かつ「B」=1or2 であり、かつ 「B」=1の取得データと「B」=2の取得データで「C」が共通していること 上記例で言えば、テーブルの1、2行目を取得したいのですが… どんなSQL文を使えば良いのか、ヒントだけでも良いのでいただけないでしょうか。 どうぞ宜しくお願いします。

  • 簡単なSQLに関して

    初歩的なSQLの質問で申し訳ありません。 教えて下さい。 下記のような、ある2つの異なる名前の同項目のテーブルが存在します。 《テーブル》 Aテーブル   社員番号、日付、内容 Bテーブル  社員番号、日付、内容  ※ 内容に関しては、AテーブルとBテーブルで全く違います。 これらの2つのテーブルをマージさせ、社員番号毎の内容毎、日付順に したいと考えています。 どのようなSQLを書けば良いでしょうか?? 尚、テーブルに関しては、諸事情であえて2つに分けてあります。 よろしくお願いします。

  • SQLの問題です。

    以下のような二つのテーブルがあります。 社員テーブル 社員番号 社員氏名 1     花子 2     太郎 所属テーブル 社員番号 所属番号 1     10 1     20 2     30 欲しいのは以下の結果です。 1 花子 2 太郎 以下のSQLを実行すると、 SELECT distinct a.社員番号, a.社員氏名, b.所属番号 FROM 社員 a,所属 b where a.社員番号 = b.社員番号 order by 所属番号 1 花子 1 花子 2 太郎 となってしまいます。 先に述べたとおりの結果を取得するにはどういうSQLを書いたらいいでしょうか? お知恵を貸してください。宜しくお願いします。 Oracle8iを使用しています。