web-dev-qa-db-fra.com

Quand utiliser une jointure externe gauche?

Je ne comprends pas le concept d'une jointure externe gauche, d'une jointure externe droite, ni même de la raison pour laquelle nous devons utiliser une jointure! La question qui me pose problème et le tableau sur lequel je travaille est ici: Link

Question 3(b) 

Construisez une commande en SQL pour résoudre la requête suivante, en expliquant pourquoi elle devait employer la méthode de jointure (Externe). [5 points] “Trouvez le nom de chaque membre du personnel et de son conjoint à charge, le cas échéant”

Question 3(c) - 

Construisez une commande en SQL pour résoudre la requête suivante, en utilisant (i) la méthode join, et (ii) la méthode Subquery. [10 points] “Trouvez le nom d’identité de chaque membre du personnel ayant travaillé plus de 20 heures sur le projet D’informatisation”

Quelqu'un peut-il s'il vous plaît m'expliquer cela simplement?

27
John Conrad

Les jointures permettent de combiner deux tables liées.

Dans votre exemple, vous pouvez combiner la table Employee et la table Department, comme suit:

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

Cela donnerait un jeu d'enregistrements comme:

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

J'ai utilisé un INNER JOIN ci-dessus. INNER JOINs combinent deux tables pour que seulement enregistrements avec des correspondances dans les deux tables soient affichés. Ils sont jointe dans le cas présent, sur le numéro du département (zone DNO dans Employee, DNUMBER dans la table Department).

LEFT JOINs vous permet de combiner deux tables lorsque vous avez des enregistrements dans la première table mais que peut-être pas des enregistrements dans la seconde table. Par exemple, supposons que vous vouliez une liste de tous les employés, plus toutes les personnes à charge:

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

Le problème ici est que si un employé n'a pas de personne à charge, son enregistrement n'apparaîtra pas du tout - car il n'y a pas d'enregistrement correspondant dans la table DEPENDENT.

Ainsi, vous utilisez une jointure left qui conserve toutes les données sur la "gauche" (c'est-à-dire la première table) et extrait les données correspondantes sur la "droite" (la deuxième table):

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

Maintenant, nous obtenons tous des enregistrements des employés. S'il n'y a pas de personne à charge correspondante pour un employé donné, les champs dependent_first et dependent_last seront nuls.

78
Jordan Reiter

exemple (sans utiliser vos exemples de tables :-)

J'ai une entreprise de location de voitures.

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

Simple droit? J'ai 10 disques pour les voitures parce que j'ai 10 voitures.
Je dirige cette entreprise depuis 10 ans et j'ai donc 1000 clients.
Et je loue les voitures environ 20x par an et par voiture = 10 ans x 10 voitures x 20 = 2000 locations.

Si je stocke tout dans une grande table, j’ai 10x1000x2000 = 20 millions d’enregistrements.
Si je le stocke dans 3 tables, j'ai 10 + 1000 + 2000 = 3010 enregistrements.
C’est 3 ordres de grandeur, c’est pourquoi j’utilise 3 tableaux. 

Mais parce que j'utilise 3 tables (pour gagner du temps et de l'espace), je dois utiliser des jointures pour récupérer les données.
(du moins si je veux des noms et des plaques d'immatriculation au lieu de chiffres).

Utilisation de jointures internes

Toutes les locations pour le client 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.

C’est un INNER JOIN, parce que nous seulement voulons connaître les voitures linked to locations linked to qui se sont réellement produites.

Notez que nous avons aussi un bike_id, relié à la table bike, qui est assez similaire à la table car mais différent .. Comment obtiendrions-nous toutes les locations de vélos + voitures pour le client 345?.
Nous pouvons essayer et faire ceci

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.

Mais cela donnera un ensemble vide !!
Ceci est dû au fait qu'une location peut être un bike_rental OR un car_rental, mais pas les deux en même temps.
Et la requête inner join qui ne fonctionne pas donnera uniquement des résultats pour toutes les locations où nous louons un vélo et une voiture dans la même transaction.
Nous essayons d’obtenir une relation booléenne OR à l’aide d’une jointure booléenne AND. 

Utilisation de jointures externes

Pour résoudre ce problème, nous avons besoin d'un outer join.

Nous allons le résoudre avec 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.

Vois-le de cette façon. Un inner join est une AND et un left join est une OR comme dans le pseudocode suivant:

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}

Si vous créez les tables et exécutez la requête, vous pouvez voir le résultat.

sur la terminologie

Un left join est identique à un left outer join. Une join sans préfixe supplémentaire est un inner join Il existe également un full outer join. En 25 ans de programmation, je n'ai jamais utilisé cela.

Pourquoi la gauche rejoindre

Eh bien, il y a deux tables impliquées. Dans l'exemple que nous avons lié
client à la location avec un inner join, dans une jointure interne, les deux tables must link afin qu’il n’y ait aucune différence entre la table left:customer et la table right:rental.

Le lien suivant était un left join entre left:rental et right:car. Sur le côté gauche, toutes les lignes doivent être liées et sur le côté droit, elles ne sont pas obligées. C'est pourquoi c'est un left join

25
Johan

Vous utilisez des jointures externes lorsque vous avez besoin de tous des résultats de l'une des tables de jointure, qu'il existe ou non une ligne correspondante dans l'autre table.

2
Oded

En général: JOIN joint deux tables ensemble . Utilisez INNER JOIN lorsque vous voulez "rechercher", comme rechercher des informations détaillées sur une colonne spécifique . Utilisez OUTER JOIN lorsque vous voulez "démontrer", comme liste toutes les informations des 2 tables.

0
Sheng Chen

Je pense que la question 3(b) est source de confusion, car son principe est faux: vous n'avez pas besoin d'utiliser une jointure externe pour "résoudre la requête", par exemple. Considérez ceci (il est probablement sage de suivre le style de syntaxe dans l'examen):

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