2017-04-19 5 views
3

私はSQLでプログラミングすることを学んでおり、セルフ・ジョインに導入されました。私はこれらの仕組みを理解していますが、非常に具体的な使用法以外の目的は何かを理解しておらず、従業員テーブルを従業員とそれぞれの管理者をきれいに表示するために参加しています。セルフ・ジョインの目的

EmployeeID | Name   | ManagerID 
    ------ | ------------- | ------ 
    1  | Sam   | 10 
    2  | Harry   | 4 
    4  | Manager  | NULL 
    10  | AnotherManager| NULL 

し、次の問合せ::戻ってくる

select worker.employeeID, worker.name, worker.managerID, manager.name 
from employee worker join employee manager 
on (worker.managerID = manager.employeeID); 

この使用法は、次の表を用いて実証することができます。このほかに

Sam AnotherManager 
Harry Manager 

、いずれかがあります自己結合が有用な他の状況?自己結合が必要なシナリオを理解することはできません。

+0

を取ることが可能であるような列の対として、「時刻表データ」の他のものを見つけるために使用することができます。http: //stackoverflow.com/questions/2458519/explanation-of-self-joins?noredirect=1&lq=1、http://stackoverflow.com/questions/3362038/what-is-self-join-and-when-would-あなたはそれを使用します。 – Nivas

答えて

3

あなたの例は良いものです。セルフ・ジョインは、表に外部キーが含まれている場合に便利です。従業員にはマネージャがあり、マネージャには...別の従業員がいます。だから、自己結合が理にかなっている。

これには多くの階層とリレーションシップツリーが適しています。たとえば、親組織が地域、グループ、チーム、オフィスに分かれているとします。それらのそれぞれは、 "組織"として、親IDを列として格納することができます。

あなたのお店やサービスが紹介プログラムを持っていて、どの顧客が誰かを紹介したかを記録したい場合があります。彼らは両方とも同じテーブルの「顧客」ですが、一方は別のテーブルへのFKリンクを持っています。

ではないの階層には、エンティティが複数の「親」リンクを持つ場合があります。たとえば、Facebookや他のユーザーとの友だちリンクを記録するFacebookのスタイルのデータがあるとします。そのとすることができますが、ユーザーが持っているすべての友人に新しい「ユーザー」行が必要です。すべての行は「relationshipUserID」列または呼び出されたものを除いて重複していますそれ。

多対多リレーションシップでは、「開始」列と「終了」列を持つ別の「リレーションシップ」テーブルと、おそらくリレーションシップタイプを示す列があります。

2

私は自分がこのような状況の中で最も便利な加入が見つかりました:

はサムと同じ管理者のために働くすべての従業員を取得します。テーブル内の重複を見つけるためにも

select e2.employeeID, e2.name 
from employee e1 join employee e2 
on (e1.managerID = e2.managerID) 
where e1.name = 'Sam' 

役立ちますが、これは非常に非効率的になります(サムと同じ場所で働くすべての従業員を取得します。これは、階層的である必要はありません、これも可能)。

0

自己結合は、同じテーブルのレコードを互いに比較したいときに便利です。例:重複住所の検索、配送先住所が請求書住所と異なる顧客の検索、日報(レコードとして保存)の合計と前日の合計との比較など

+1

例はあまりよくありません。 'GROUP BY' +' HAVING COUNT(*).... 'は重複(および不一致)を見つけるより効率的な方法です。 – mathguy

1

ここで自己結合を使う素晴らしい例です。私がよく使うのは「時間割」です。私は教育のタイムテーブルを使って仕事をしていますが、他の場合も同様です。

2つのアイテムが互いに衝突するかどうかを判断するために自己結合を使用します。学生は同時に2つのレッスンを予定しています。また、部屋は2倍に予約されています。例えば:

CREATE TABLE StudentEvents(
    StudentId int, 
    EventId int, 
    EventDate date, 
    StartTime time, 
    EndTime time 
) 

SELECT 
    se1.StudentId, 
    se1.EventDate, 
    se1.EventId Event1Id, 
    se1.StartTime as Event1Start, 
    se1.EndTime as Event1End, 
    se2.StartTime as Event2Start, 
    se2.EndTime as Event2End, 
FROM 
    StudentEvents se1 
    JOIN StudentEvents se2 ON 
     se1.StudentId = se2.StudentId 
     AND se1.EventDate = se2.EventDate 
     AND se1.EventId > se2.EventId 
     --The above line prevents (a) an event being seen as clashing with itself 
     --and (b) the same pair of events being returned twice, once as (A,B) and once as (B,A) 
WHERE 
    se1.StartTime < se2.EndTime AND 
    se1.EndTime > se2.StartTime 

同様のロジックは、C.

にBを経由してAから関連
関連する問題