自己結合の説明


84

自己結合の必要性がわかりません。誰かが私にそれらを説明してもらえますか?

簡単な例が非常に役立ちます。

回答:


95

自己結合は、2つの同一のテーブルとして表示できます。ただし、正規化では、テーブルの2つのコピーを作成できないため、自己結合を使用して2つのテーブルを持つことをシミュレートするだけです。

2つのテーブルがあるとします。

テーブル emp1

Id Name Boss_id            
1   ABC   3                   
2   DEF   1                   
3   XYZ   2                   

テーブル emp2

Id Name Boss_id            
1   ABC   3                   
2   DEF   1                   
3   XYZ   2                   

ここで、各従業員の名前と上司の名前を取得する場合は、次のようにします。

select c1.Name , c2.Name As Boss
from emp1 c1
    inner join emp2 c2 on c1.Boss_id = c2.Id

次の表が出力されます。

Name  Boss
ABC   XYZ
DEF   ABC
XYZ   DEF

1
この例では、誰が上司かわかりません。経験は良くて理解しやすいですが。
MAC

2
left join上司がいない従業員(または上司)を除外しないほうがいいと思います。トップ犬!
Rockin4Life33 2018

22

それ自体を参照するテーブルがある場合、それは非常に一般的です。例:すべての従業員がマネージャーを持つことができ、すべての従業員とそのマネージャーの名前を一覧表示する従業員テーブル。

SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id

18

自己結合は、テーブルとそれ自体の結合です。

一般的な使用例は、テーブルに、それらの間に階層関係を持つエンティティ(レコード)が格納されている場合です。たとえば、個人情報(名前、DOB、住所など)を含み、父親(および/または母親)のIDが含まれる列を含むテーブル。次に、のような小さなクエリで

SELECT Child.ID, Child.Name, Child.PhoneNumber, Father.Name, Father.PhoneNumber
FROM myTableOfPersons As Child
LEFT OUTER JOIN  myTableOfPersons As Father ON Child.FatherId = Father.ID
WHERE Child.City = 'Chicago'  -- Or some other condition or none

同じクエリで、子供と父親の両方(および母親、2番目の自己結合など、さらには祖父母など)に関する情報を取得できます。


5

次のusersように設定されたテーブルがあるとします。

  • ユーザーID
  • ユーザー名
  • ユーザーのマネージャーのID

この状況で、ユーザーの情報マネージャーの情報の両方を1つのクエリで取得する場合は、次のようにします。

SELECT users.user_id, users.user_name, managers.user_id AS manager_id, managers.user_name AS manager_name INNER JOIN users AS manager ON users.manager_id=manager.user_id

4

これらは、テーブルが自己参照型である場合に役立ちます。たとえば、ページのテーブルの場合、各ページにnextpreviousリンクが含まれる場合があります。これらは、同じテーブル内の他のページのIDになります。ある時点で、連続するページのトリプルを取得したい場合は、同じテーブルの列を持つ列nextprevious列で2つの自己結合を実行しidます。


4

Employee以下に説明するように呼び出されたテーブルを想像してみてください。すべての従業員には、従業員でもあるマネージャーがいます(おそらく、manager_idがnullになるCEOを除く)

Table (Employee): 

int id,
varchar name,
int manager_id

次に、次の選択を使用して、すべての従業員とそのマネージャーを検索できます。

select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id

4

テーブルがそれ自体を参照する機能がなければ、階層内のレイヤーの数と同じ数の階層レベルのテーブルを作成する必要があります。ただし、その機能が利用できるため、テーブルをそれ自体に結合すると、SQLはそれを2つの別個のテーブルとして扱い、すべてが1つの場所に適切に格納されます。


しかし今、あなたは(うまくいけば)自己参照が利用できなかった場合に何が起こるかを理解しています。
ユージーン

4

上記の回答(非常によく説明されています)とは別に、自己結合の使用法を簡単に示すことができるように、1つの例を追加したいと思います。次の属性を持つCUSTOMERSという名前のテーブルがあるとします:CustomerID、CustomerName、ContactName、City、Country。ここで、「同じ都市」から来たすべての人をリストします。CITYに基づいて結合できるように、このテーブルのレプリカを考える必要があります。以下のクエリは、それが何を意味するかを明確に示しています。

SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2, 
A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City 
ORDER BY A.City;

3
+1この回答は非常に重要です。SOには「自己結合を使用する」というSQLの質問が非常に多く、明示的な(階層的な)自己参照がない場合は表示されない傾向があるためです。
JimmyB 2018

1
これはw3schoolsのコピーパスタですが、上記の答えは自己結合ではなく、内部結合とは異なります。
ジョージ

3

ここには多くの正解がありますが、同様に正しいバリエーションがあります。WHERE句の代わりにjoinステートメントに結合条件を配置できます。

SELECT e1.emp_id AS 'Emp_ID'
  , e1.emp_name AS 'Emp_Name'
  , e2.emp_id AS 'Manager_ID'
  , e2.emp_name AS 'Manager_Name'
FROM Employee e1 RIGHT JOIN Employee e2 ON e1.emp_id = e2.emp_id

e1.manager_id> e2.idが必要な場合があることに注意してください

両方のシナリオを知っていることの利点は、WHEREまたはJOIN条件が大量にあり、コードを読みやすくするために、自己結合条件を他の句に配置したい場合があることです。

従業員にマネージャーがいない場合に何が起こるかについては誰も話しませんでした。え?それらは結果セットに含まれません。マネージャーがいない従業員を含めたいが、間違った組み合わせを返したくない場合はどうなりますか?

この子犬を試してみてください。

SELECT e1.emp_id AS 'Emp_ID'
   , e1.emp_name AS 'Emp_Name'
   , e2.emp_id AS 'Manager_ID'
   , e2.emp_name AS 'Manager_Name'
FROM Employee e1 LEFT JOIN Employee e2 
   ON e1.emp_id = e2.emp_id
   AND e1.emp_name = e2.emp_name
   AND e1.every_other_matching_column = e2.every_other_matching_column

1
うーん、子犬では、なぜ「等しい」ではなく「より大きい」に参加するのですか?
マルセル

1
こんにちは。いくつかの例では「FROMxxx、yyyWHERE」と他のいくつかの「FROMxxxJOINyyyWHERE」を使用しているのを見てきました。違いを教えてください。
skan 2014

@Skanそれは本当に良い質問です。簡単な答えは、これは古い速記法であり、非推奨になるということです。私は10年以上前に学校でそれを使用しましたが、実際にはめったに見ません。ここで私は見つけることができる最も簡潔な説明です:bidn.com/blogs/KathiKellenberger/sql-server/2875/...
BClaydon

1

1つのユースケースは、データベース内の重複レコードをチェックすることです。

SELECT A.Id FROM My_Bookings A, My_Bookings B
WHERE A.Name = B.Name
AND A.Date = B.Date
AND A.Id != B.Id

重複を見つけるためにGROUPBYとHAVING句を使用する方がはるかに高速です。SELECT name、email、COUNT()FROM My_Bookings GROUP BY name、date HAVING COUNT()> 1
George K

@GeorgeKTrue。これは、あいまい一致(TRIM(LOWER(Name))によるグループ化以外)にのみ必要であり、厳密な同等性には必要ないと思います。
Steven Stewart-Gallus 2018

1

自己結合は、テーブルのデータをそれ自体で評価する必要がある場合に役立ちます。つまり、同じテーブルの行を相互に関連付けます。

Syntax: SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName

たとえば、初期指定が現在の指定と等しい従業員の名前を検索したいとします。これは、次の方法で自己結合を使用して解決できます。

SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId

0

これは、リンクリスト/ツリーに相当するデータベースであり、行には別の行への参照がある程度含まれています。


実際、複数の行が「親」を参照できることを考えると、よく引用されるemployee-> managerの例のように、ツリーにすることもできます。
NVRAM

私は単純な例えを試みていましたが、そうです、木も機能します。
スライスされていない2010年

-4

これは、素人の言葉での自己結合の説明です。自己結合は別の種類の結合ではありません。他のタイプの結合(内部結合、外部結合、および相互結合)を理解している場合は、自己結合は簡単です。INNER、OUTER、およびCROSS JOINSでは、2つ以上の異なるテーブルを結合します。ただし、自己結合では、同じテーブルをitslefで結合します。ここでは、2つの異なるテーブルはありませんが、テーブルエイリアスを使用して同じテーブルを別のテーブルとして扱います。それでもはっきりしない場合は、次のYouTubeビデオをご覧になることをお勧めします。

例を使用した自己結合

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.