質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

1917閲覧

OracleのSQL発行で ツリー構造のデータを表示させたいが 最上位の表示方法に困っている

saya24

総合スコア227

Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2021/08/31 13:56

編集2021/09/01 07:12

当社製造業なのですが、よくある基幹システムのように、製品構成マスタというものを有しており
製造品に対する利用子部品を、親子関係(一階層下のみ)で定義づけています。

左図は Oracle内の製品構成マスタというテーブルで、一レコードによって 製造品と利用部品の親子関係を定義している様子、
右図は それらレコードの組合わせ=幾つかの製造品を更に組み合わせることで はじめて市場出荷される最終製品が仕上がることをイメージ頂くために ご用意させて頂いたものです。
イメージ説明

【困っていること】

指定の品目(検索の祖先)を 交えた表示を達成したいのですが、指定値が複数の場合の対処方法が分からずに困っています。
イメージ説明

【自分が試したこと】

こちらの記事を参考に、本日初めて CONNECT BY やら START WITHを使って 以下の発行文を作成しました。
単独指定の場合(以下発行分はIN句なのに単独指定)は 一応に結果を得られるのですが
本来のIN句らしく 幾つかの製造品目をこの括弧内に指定したい、というのが望みです!!

(出荷を取りやめた最終製品の一覧から 不要な製造中間体と購入原料を一気に抽出したい!  ■20210831 1613追記■ 実行時の指定は 最終製品と限らず 自身が子部品として位置付けられた製造中間体も含みます。)

ORACLE

1SELECT B.親品目コード 検索指定, A.親品目コード, A.子品目コード FROM 2(SELECT 親品目コード, 子品目コード FROM 製品構成マスタ START WITH 親品目コード IN ('A001') CONNECT BY PRIOR 子品目コード=親品目コード) A 3LEFT OUTER JOIN 4(SELECT DISTINCT 親品目コード FROM 製品構成マスタ WHERE 親品目コード IN ('A001')) B ON 1=1

どなたか対応法を存じ上げていたら教えて頂けたら幸いです、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2021/08/31 15:22

何度も書いていると思うけど、質問に使っているテーブルのCREATE TABLE文とINSERT文を何件か追加できた方がコメントが付き易いかと。
guest

回答2

0

ベストアンサー

以下のようなクエリで実現できるかと思います。

SQL

1SELECT CONNECT_BY_ROOT 親品目コード, 親品目コード, 子品目コード 2FROM 製品構成マスタ 3START WITH 親品目コード IN ('A001', 'A101') 4CONNECT BY PRIOR 子品目コード = 親品目コード;

あるいはWITHによる再帰SQLを利用して、以下のように書くこともできます。

SQL

1WITH R (検索指定, 親品目コード, 子品目コード) AS ( 2 SELECT 親品目コード, 親品目コード, 子品目コード 3 FROM 製品構成マスタ 4 WHERE 親品目コード IN ('A001', 'A101') 5 UNION ALL 6 SELECT R.検索指定, S.親品目コード, S.子品目コード 7 FROM 製品構成マスタ S 8 JOIN R ON S.親品目コード = R.子品目コード 9) 10SELECT * FROM R;

投稿2021/09/01 07:40

neko_the_shadow

総合スコア2273

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/09/01 07:53

neko_the_shadowさん、お時間を頂きありがとうございます。 手元で確認したところ、重複した行が返ってきてしまいました。 上下両方ともです。 まずはご報告まで
neko_the_shadow

2021/09/01 08:38 編集

重複した行というのは具体的にどのようなものでしょうか? その事象は提示いただいているサンプルデータにおいて発生しますか?
mayu-

2021/09/01 08:53

私もneko_the_shadowさんのSQLを実施して saya24さんご希望の結果セットが返ってくるのが確認できました。 connect_by_root演算子で簡単に記述できましたね。素敵です。
saya24

2021/09/01 10:23 編集

申し訳ありません、重複の事象発生は 社内の実データで確認していたならではの状況でした。混乱を与え申し訳ございませんでした。(使用開始日と使用停止日の別フィールドで、同一親子品目関係のレコードを期間違いで保持できるようになっている。使用料とか季節で違う) で、単純に 大大大満足な結果を得られて 非常に感激しています!!! いくら感謝しても感謝しきれません、この発行文は絶対幅広い分野で活用していけるとも今から確信しております。本当にありがとうございました。
guest

0

指定の品目(検索の祖先)を 交えた表示を達成したいのですが、
指定値が複数の場合の対処方法が分からずに困っています。

ご提示いただいた製品構成マスタテーブルのサンプルデータには
ルートノード( 検索指定列に表示されているA001 )を特定できるレコードが見当たらない...ですね。

そのため、ご希望の抽出方法を実装するためにはSQL文において
「 親品目コードには存在するけれども、子品目コードには存在しない 」
という条件に合致した品目コードルートノードとして定義する必要があるでしょう。

以下のような感じでどうでしょうか。
( WITH句でのルートノード特定方法がとてつもなくダサいのはご容赦 )

SQL

1WITH saya24 ( parent, child, path, hierarchy, root ) AS 2( 3 SELECT parent 4 , child 5 , sys_connect_by_path( q.child, '/' ) 6 , level 7 , case 8 when level = 1 9 then 10 substr( sys_connect_by_path( q.child, '/' ), 2 ) 11 else 12 substr( sys_connect_by_path( q.child, '/' ) 13 , 2 14 , instr( sys_connect_by_path( q.child, '/' ), '/', 1, 2 ) - 2 15 ) 16 end 17 FROM 18 ( 19 SELECT 子品目コード child, 親品目コード parent 20 FROM 製品構成マスタ 21 22 UNION ALL 23 24 SELECT 親品目コード, 'root' 25 FROM 製品構成マスタ 26 MINUS 27 SELECT 子品目コード, 'root' 28 FROM 製品構成マスタ 29 ) q 30 start with parent = 'root' 31 connect by prior child = parent 32) 33 34SELECT * 35 FROM saya24 36 WHERE root IN ( 'A001' ) 37;

 
■結果

result

1parent child    path     hierarchy   root 2------------------------------------------------------ 3root  A001  /A001         1    A001 4A001  B001  /A001/B001       2    A001 5B001  C002  /A001/B001/C002    3    A001 6C002  F002  /A001/B001/C002/F002  4    A001 7C002  F003  /A001/B001/C002/F003  4    A001 8C002  G001  /A001/B001/C002/G001  4    A001 9B001  C003  /A001/B001/C003    3    A001 10B001  D001  /A001/B001/D001    3    A001 11A001  B002  /A001/B002       2    A001 12B002  D002  /A001/B002/D002    3    A001 13B002  D003  /A001/B002/D003    3    A001 14B002  E001  /A001/B002/E001    3    A001 15A001  B101  /A001/B101       2    A001 16B101  C102  /A001/B101/C102    3    A001 17B101  C103  /A001/B101/C103    3    A001 18B101  D101  /A001/B101/D101    3    A001 19A001  B102  /A001/B102       2    A001 20A001  C001  /A001/C001       2    A001 21C001  E002  /A001/C001/E002    3    A001 22C001  E003  /A001/C001/E003    3    A001 23C001  F001  /A001/C001/F001    3    A001 24A001  C101  /A001/C101       2    A001

投稿2021/09/01 04:47

編集2021/09/01 05:40
mayu-

総合スコア335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/09/01 05:30

mayuさん、ご回答をありがとうございます。一読しただけでございますが 発行結果を得ようとする際の 指定値は 最上位とは 限らないのですが 対応できるご提案でしょうか? 文面をみて まず気になりました 原価が高い工程品=製造中間体を指定し 原材料を見直すなど、ほんと どこの位置の品目を指定されるかわからないものを作ろうとしています。 発行文を期待しておりますが、ご提案がWITHから始まっておりますね?、初めて拝見いたしましたが SQLPLUSなどで 正常に発行できるのでしょうか、 無知ですみません....
mayu-

2021/09/01 06:23

> 指定値は 最上位とは 限らないのですが 対応できるご提案でしょうか 下の階層でしたら比較的容易に対応できるでしょう。 ( ご提示のテーブル構造では「 最上位 」の複数指定が一番難しい ) 私が記述したSQL文で申し上げるなら hierarchy と parent の両フィールドに適宜、抽出条件を記述します。 なお、指定する階層が「 最上位とは限らない 」という重要な文言は コメント欄ではなく、予めご質問に明記しておくことをお薦めします。 なにはともあれ、あれもこれもと一気に解決しようとするのではなく 問題点を1点に絞り、一歩一歩 完成に近づくようになさったほうがいいでしょう。 > ご提案がWITHから始まっておりますね?、 > 初めて拝見いたしましたが SQLPLUSなどで 正常に発行できるのでしょうか ご利用のバージョンが 9i以降 でしたら使えます。 SQL*Plusでも発行可能です。 ちなみに 共通テーブル式( WITH )で記述している部分は FROM句のインラインビューとして記述する方法もありますから 興味がおありなら、ご自身でチャレンジなさってみるといいでしょう。
saya24

2021/09/01 07:57

大事なこと=最上位の指定とは限らない ことの本文への記載を漏らしてしまい 申し訳ございませんでした。試してみたところ仰るように それ前提の作りのご提案であり 手を加える必要がある、ということですね。失敗!! 工程途中の製造品を指定できるように まずは理解を進めます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問