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

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

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

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

Q&A

解決済

5回答

10836閲覧

SQLの自己結合について

退会済みユーザー

退会済みユーザー

総合スコア0

SQL

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

0グッド

0クリップ

投稿2016/10/17 01:34

SQLの自己結合について質問です。

上のようなテーブルに対して、次のようなSQLを実行した時、
イメージ説明

このような結果を得ることができます。
イメージ説明

SQL内のサブクエリの部分が理解できれば、簡単にわかるのですが、サブクエリの部分がイマイチどのように実行されているか分かりません。
色々調べてみたのですが、よく分かりませんでした。
二つの組織図テーブルをスキャンさせているわけでもなさそうですし。。

お分かりの方、少し解説していただけないでしょうか?

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

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

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

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

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

guest

回答5

0

ベストアンサー

自己結合と相関副問合わせが混在して分からなくなってる感があるので、
一つずつ整理すると良いかもしれません。

#自己結合
先ず自己結合だけに絞ると、maisumakunさんの仰るとおりです。
テーブル別名を付ける(ここでは部下・上司)ことで実態は1つテーブルでも、
それぞれが別のテーブルとして振舞わせることができます。

直感的に分かりやすいようテーブル構成をもっと単純化してみます。

  • 社員マスタ
社員コード社員名上司コード
101キラ・ヤマトNULL
201アスラン・ザラNULL
301シン・アスカ201

上記のテーブルで「シン・アスカ」さんの上司名を知りたい・・・、
といった場合に自己結合が用いられます。
SQLにすると以下のような感じ。

SQL

1SELECT 2 上司.社員名 -- あんたって人はー!! 3FROM 4 社員マスタ 上司 5 INNER JOIN 社員マスタ 社員 6 ON 上司.社員コード = 社員.上司コード 7WHERE 8 社員.社員名 = 'シン・アスカ'

まぁつまるところ別名を付けると、
別テーブルとして扱えるから結合でもサブクエリでも書けるよねってお話ですね。

#相関副問合わせ
相関副問合せと書くと難しそうに聞こえますが、
要するにメイン側のクエリ(今回だと一番外側のクエリ)の結果1行に対して動作するクエリのことを指します。
今回の例だとNOT EXISTS句内のクエリは、
上司と別名を付けられた組織図のレコード1行ごとに動作するものとなります。

例えばメイン側のクエリで取り出したレコードが「アダム」の場合、
NOT EXISTS内のクエリは下記のように評価されます。

SQL

1SELECT 2 * 3FROM 4 組織図 部下 5WHERE 6 部下.左端 > 1 -- (アダムの左端の値) 7AND 部下.左端 < 14 -- (アダムの右端の値)

今回はNOT EXISTS句なので、
上記クエリの検索結果がO件の場合のみ「TRUE」を返します。
(※つまりメイン側のクエリのWHERE条件で抽出対象になる)

これを残りのレコード分(イブ~ノアのデータ)反復処理されます。

これと反対にEXISTS句というのもありますが、
これは反対にレコードが1件でもあれば「TRUE」を返し、
0件の場合は「FALSE」と評価されます。

ちなみに相関副問合せは今回のように、
メイン側クエリ抽出データ1件ごとに動作し、
それ単体では成立し得ないサブクエリのことを、
特に他のサブクエリと区別して「相関副問合せ」とか「相関サブクエリ」とか呼ばれたりします。
(まぁ結局サブクエリの仲間ではあるんですがね・・・)

投稿2016/10/17 13:25

編集2016/10/17 13:32
Panzer_vor

総合スコア1636

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

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

退会済みユーザー

退会済みユーザー

2016/10/18 07:00

回答ありがとうございます。
guest

0

副照会の条件

上司の立場で部下がいるかどうか確認します。
「上司.左端 < 部下.左端 < 上司.右端」となる部下がいるかどうか。
NOT EXISTSなので部下がいない上司が選択されます。

アダム 1 14 が上司の場合の部下
イブ 2 3
セト 4 13
カイン 5 8
ヨブ 6 7
アベル 9 10
ノア 11 12

イブ 2 3 が上司の場合の部下

セト 4 13 が上司の場合の部下
カイン 5 8
ヨブ 6 7
アベル 9 10
ノア 11 12

カイン 5 8 が上司の場合の部下
ヨブ 6 7

ヨブ 6 7 が上司の場合の部下

アベル 9 10 が上司の場合の部下

ノア 11 12 が上司の場合の部下

結論 <<部下がいない上司は?>>

イブ 2 3
ヨブ 6 7
アベル 9 10
ノア 11 12

###結合ですか?(追記)
これは自己結合ですか?ただの副問い合わせではないでしょうか?
次のように明に記述する自己結合(部下のいる上司)なら納得しますが。

SQL

1select distinct 上司.社員 from 組織図 上司 2join 組織図 部下 on (上司.左端 < 部下.左端 and 部下.左端 < 上司.右端);

投稿2016/10/17 13:11

編集2016/10/17 14:26
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2016/10/18 07:00

具体例を示してくださり、ありがとうございました。 非常に分かりやすかったです。
guest

0

もしもDBの構造自体(入れ子集合モデル)が不明瞭であれば
http://www.geocities.jp/mickindex/database/db_tree_ns.html
をご覧いただくとよいかも知れません。

投稿2016/10/17 04:51

koutan1976

総合スコア142

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

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

退会済みユーザー

退会済みユーザー

2016/10/18 07:00

回答ありがとうございました。
guest

0

以下を実行するとイメージがわかりやすいかもしれません

SQL

1create table sosikizu(no varchar(20),l int ,r int); 2insert into sosikizu values('アダム',1,14),('イブ',2,3),('セト',4,13),('カイン',5,8),('ヨブ',6,7),('アベル',9,10),('ノア',11,12);

実行

select * from sosikizu as t1 inner join sosikizu as t2 on t2.l>t1.l and t2.l<t1.r order by t1.l,t2.l;

上記実行すると上司と部下の関係図がわかります。
これがNOT EXISTSなので、組織図から上司とっぱらうと部下のみが表示されます

投稿2016/10/17 04:29

yambejp

総合スコア114812

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

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

退会済みユーザー

退会済みユーザー

2016/10/18 07:01

回答ありがとうございました。
guest

0

二つの組織図テーブルをスキャンさせているわけでもなさそうですし。。

物理的な挙動はともかく、SQLの処理の上では、あたかも「上司」と「部下」という2つのテーブルがあるかのように動きます。実物が1枚しかないことは忘れて、「二つの組織図テーブルをスキャンさせている」と考えてください。

投稿2016/10/17 02:28

編集2016/10/17 02:30
maisumakun

総合スコア145183

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

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

退会済みユーザー

退会済みユーザー

2016/10/18 07:01

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問