左外部結合、右外部結合の概念、または実際に結合を使用する必要がある理由を理解していません!私が苦労している質問と私が働いているテーブルはここにあります: Link
質問3(b)
SQLでコマンドを作成して次のクエリを解決し、(外部)結合メソッドを使用する必要がある理由を説明します。 [5マーク]「各スタッフメンバーとその配偶者の名前があれば、それを見つけます」
質問3(c)-
SQLでコマンドを作成して、(i)joinメソッドと(ii)subqueryメソッドを使用して、次のクエリを解決します。 [10点]「コンピューター化プロジェクトで20時間以上働いた各スタッフの識別名を見つけてください」
誰でも簡単にこれを説明してもらえますか?
結合は、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 JOIN
sは2つのテーブルを結合し、両方のテーブルに一致するonlyレコードが表示され、これらはjoinedになりますケース、部門番号(従業員のフィールドDNO、部門テーブルのDNUMBER)。
LEFT JOIN
sを使用すると、最初のテーブルにレコードがあるが、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になります。
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 join
はAND
であり、left join
はOR
です。
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 join
はleft outer join
と同じです。余分なプレフィックスのないjoin
はinner join
です。full outer join
もあります。プログラミングの25年間で、私はそれを使用したことがありません。
左結合の理由
2つのテーブルが関係しています。リンクした例ではinner join
を使用してレンタルする顧客は、内部結合で両方のテーブルmustリンクを使用するため、left:customer
テーブルとright:rental
テーブル。
次のリンクは、left join
とleft:rental
の間のright:car
でした。左側ではすべての行がリンクする必要があり、右側ではリンクする必要はありません。これがleft join
である理由です
他のテーブルに一致する行があるかどうかに関係なく、結合テーブルの1つからの結果のallが必要な場合は、外部結合を使用します。
一般的に:JOINは2つのテーブルを結合します。特定の列の詳細情報を検索するなど、「検索」する場合は、INNER JOINを使用します。 2つのテーブルのすべての情報を一覧表示するなど、「デモンストレーション」する場合は、OUTER JOINを使用します。
質問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'