web-dev-qa-db-ja.com

左外部結合を使用する場合

左外部結合、右外部結合の概念、または実際に結合を使用する必要がある理由を理解していません!私が苦労している質問と私が働いているテーブルはここにあります: Link

質問3(b)

SQLでコマンドを作成して次のクエリを解決し、(外部)結合メソッドを使用する必要がある理由を説明します。 [5マーク]「各スタッフメンバーとその配偶者の名前があれば、それを見つけます」

質問3(c)-

SQLでコマンドを作成して、(i)joinメソッドと(ii)subqueryメソッドを使用して、次のクエリを解決します。 [10点]「コンピューター化プロジェクトで20時間以上働いた各スタッフの識別名を見つけてください」

誰でも簡単にこれを説明してもらえますか?

29
John Conrad

結合は、2つの関連するテーブルを結合するために使用されます。

この例では、次のようにEmployeeテーブルとDepartmentテーブルを組み合わせることができます。

SELECT FNAME, LNAME, DNAME
FROM
EMPLOYEE INNER JOIN DEPARTMENT ON EMPLOYEE.DNO=DEPARTMENT.DNUMBER

これにより、次のようなレコードセットが作成されます。

FNAME   LNAME   DNAME
-----   -----   -----
John    Smith   Research
John    Doe     Administration

上記のINNER JOINを使用しました。 INNER JOINsは2つのテーブルを結合し、両方のテーブルに一致するonlyレコードが表示され、これらはjoinedになりますケース、部門番号(従業員のフィールドDNO、部門テーブルのDNUMBER)。

LEFT JOINsを使用すると、最初のテーブルにレコードがあるが、2番目のテーブルにない場合があるがある場合に2つのテーブルを結合できます。たとえば、すべての従業員と扶養家族のリストが必要だとしましょう:

SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_last, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE INNER JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN

ここでの問題は、従業員が扶養家族を持たない場合、DEPENDENTテーブルに一致するレコードがないため、そのレコードがまったく表示されないことです。

したがって、left結合を使用します。これは、「左」(つまり最初のテーブル)のすべてのデータを保持し、「右」(2番目のテーブル):

SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_first, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE LEFT JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN

これで、従業員レコードのallが取得されます。特定の従業員に一致する扶養家族がいない場合、dependent_firstおよびdependent_lastフィールドはnullになります。

82
Jordan Reiter

example(サンプルテーブルを使用しない:-)

レンタカー会社があります。

Table car
id: integer primary key autoincrement
licence_plate: varchar
purchase_date: date

Table customer
id: integer primary key autoincrement
name: varchar

Table rental
id: integer primary key autoincrement
car_id: integer
bike_id: integer
customer_id: integer
rental_date: date

簡単でしょう?車が10台あるので、車のレコードは10個あります。
私はこのビジネスを10年間運営しているため、1000人の顧客を獲得しています。
そして、私は車1台あたり年間20倍= 10年x 10台x 20 = 2000台のレンタルをしています。

1つの大きなテーブルにすべてを格納すると、10x1000x2000 = 2000万レコードになります。
3つのテーブルに保存すると、10 + 1000 + 2000 = 3010レコードになります。
これは3桁であるため、3つのテーブルを使用します。

しかし、3つのテーブルを使用しているため、(スペースと時間を節約するために)データを再度取得するには、結合を使用する必要があります
(少なくとも数字の代わりに名前とナンバープレートが必要な場合)

内部結合の使用

顧客345のすべてのレンタル?

SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
WHERE customer.id = 345.

それはINNER JOINです。なぜなら、私たちはonlyについて知りたいだけですlinked toレンタルlinked to実際に起こった顧客。

また、bikeテーブルにリンクするbike_idもあります。これは、carテーブルとかなり似ていますが、異なります。顧客345のすべての自転車とレンタカーをどのように取得しますか。
tryして、これを行うことができます

SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
INNER JOIN bike on (bike.id = rental.bike_id)
WHERE customer.id = 345.

しかし、それは空のセットになります!!
これは、レンタルがbike_rental OR car_rentalのいずれかである場合がありますが、両方を同時に使用することはできません。
また、動作しないinner joinクエリは、同じトランザクションで自転車と車の両方をレンタルするすべてのレンタルの結果のみを返します。
boolean OR joinを使用して、boolean AND関係を取得しようとしています。

外部結合の使用

これを解決するには、outer joinが必要です。

left joinで解決しましょう

SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id) <<-- link always
LEFT JOIN car on (car.id = rental.car_id) <<-- link half of the time
LEFT JOIN bike on (bike.id = rental.bike_id) <<-- link (other) 0.5 of the time.
WHERE customer.id = 345.

このように見てください。次の擬似コードのように、inner joinANDであり、left joinORです。

if a=1 AND a=2 then {this is always false, no result}
if a=1 OR a=2 then  {this might be true or not}

テーブルを作成してクエリを実行すると、結果を確認できます。

用語について

left joinleft outer joinと同じです。余分なプレフィックスのないjoininner joinです。full outer joinもあります。プログラミングの25年間で、私はそれを使用したことがありません。

左結合の理由

2つのテーブルが関係しています。リンクした例では
inner joinを使用してレンタルする顧客は、内部結合で両方のテーブルmustリンクを使用するため、left:customerテーブルとright:rentalテーブル。

次のリンクは、left joinleft:rentalの間のright:carでした。左側ではすべての行がリンクする必要があり、右側ではリンクする必要はありません。これがleft joinである理由です

25
Johan

他のテーブルに一致する行があるかどうかに関係なく、結合テーブルの1つからの結果のallが必要な場合は、外部結合を使用します。

2
Oded

一般的に:JOINは2つのテーブルを結合します。特定の列の詳細情報を検索するなど、「検索」する場合は、INNER JOINを使用します。 2つのテーブルのすべての情報を一覧表示するなど、「デモンストレーション」する場合は、OUTER JOINを使用します。

0
Sheng Chen

質問3(b)はその前提全体が間違っているため、混乱していると思います。「クエリを解決する」ために外部結合を使用する必要はありません。試験用紙はおそらく賢明です):

SELECT FNAME, LNAME, DEPENDENT_NAME
  FROM EMPLOYEE, DEPENDENT
 WHERE SSN = ESSN
       AND RELATIONSHIP = 'SPOUSE'
UNION 
SELECT FNAME, LNAME, NULL
  FROM EMPLOYEE
EXCEPT 
SELECT FNAME, LNAME, DEPENDENT_NAME
  FROM EMPLOYEE, DEPENDENT
 WHERE SSN = ESSN
       AND RELATIONSHIP = 'SPOUSE'
0
onedaywhen