web-dev-qa-db-fra.com

Explication des auto-jointures

Je ne comprends pas la nécessité des auto-jointures. Quelqu'un peut-il me les expliquer?

Un exemple simple serait très utile.

Vous pouvez afficher l'auto-jointure comme deux tables identiques. Mais dans la normalisation, vous ne pouvez pas créer deux copies de la table, vous simulez simplement deux tables avec auto-jointure.

Supposons que vous ayez deux tables:

Table emp1

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

Table emp2

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

Maintenant, si vous voulez obtenir le nom de chaque employé avec les noms de son patron:

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

Qui affichera le tableau suivant:

Name  Boss
ABC   XYZ
DEF   ABC
XYZ   DEF
85
pointlesspolitics

C'est assez courant lorsque vous avez un tableau qui se référence lui-même. Exemple: une table des employés où chaque employé peut avoir un responsable, et vous souhaitez lister tous les employés et le nom de leur responsable.

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

Une auto-jointure est une jointure d'une table avec elle-même.

n cas d'utilisation courant est lorsque la table stocke des entités (enregistrements) qui ont une relation hiérarchique entre elles. Par exemple, un tableau contenant des informations sur la personne (nom, date de naissance, adresse ...) et incluant une colonne où l'ID du père (et/ou de la mère) est incluse. Puis avec une petite requête comme

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

nous pouvons obtenir des informations sur l'enfant et le père (et la mère, avec une deuxième auto-inscription, etc. et même les grands-parents, etc.) dans la même requête.

17
mjv

Disons que vous avez une table users, configurée comme suit:

  • identifiant d'utilisateur
  • nom d'utilisateur
  • iD du responsable de l'utilisateur

Dans cette situation, si vous souhaitez extraire à la fois les informations de l'utilisateur et les informations du gestionnaire dans une seule requête, vous pouvez le faire:

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
5
ceejayoz

Outre les réponses mentionnées ci-dessus (qui sont très bien expliquées), je voudrais ajouter un exemple pour que l'utilisation de Self Join puisse être facilement montrée. Supposons que vous ayez une table nommée CUSTOMERS qui possède les attributs suivants: CustomerID, CustomerName, ContactName, City, Country. Maintenant, vous voulez lister tous ceux qui sont de la "même ville". Vous devrez penser à une réplique de ce tableau afin que nous puissions les rejoindre sur la base de CITY. La requête ci-dessous montrera clairement ce que cela signifie:

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;
4
Mazhar MIK

Ils sont utiles si votre table est auto-référentielle. Par exemple, pour un tableau de pages, chaque page peut avoir un lien next et previous. Il s'agit des ID des autres pages du même tableau. Si à un moment donné vous souhaitez obtenir un triple de pages successives, vous feriez deux auto-jointures sur les colonnes next et previous avec la colonne id de la même table.

4
Max Shawabkeh

Imaginez une table appelée Employee comme décrit ci-dessous. Tous les employés ont un manager qui est également un employé (peut-être à l'exception du PDG, dont manager_id serait nul)

Table (Employee): 

int id,
varchar name,
int manager_id

Vous pouvez ensuite utiliser la sélection suivante pour rechercher tous les employés et leurs responsables:

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

Sans la possibilité pour une table de se référencer, il nous faudrait créer autant de tables pour les niveaux de hiérarchie que le nombre de couches dans la hiérarchie. Mais puisque cette fonctionnalité est disponible, vous joignez la table à elle-même et sql la traite comme deux tables distinctes, donc tout est bien stocké en un seul endroit.

4
Eugene

Il existe de nombreuses réponses correctes ici, mais il existe une variation tout aussi correcte. Vous pouvez placer vos conditions de jointure dans l'instruction join au lieu de la clause WHERE.

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

Gardez à l'esprit que vous voulez parfois e1.manager_id> e2.id

L'avantage de connaître les deux scénarios est parfois que vous avez une tonne de conditions WHERE ou JOIN et que vous souhaitez placer vos conditions d'auto-jointure dans l'autre clause pour garder votre code lisible.

Personne n'a abordé ce qui se passe lorsqu'un employé n'a pas de gestionnaire. Hein? Ils ne sont pas inclus dans le jeu de résultats. Que se passe-t-il si vous souhaitez inclure des employés qui n'ont pas de directeurs mais que vous ne voulez pas que des combinaisons incorrectes soient renvoyées?

Essayez ce chiot;

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
3
BClaydon

L'auto-jointure est utile lorsque vous devez évaluer les données de la table avec elle-même. Ce qui signifie qu'il corrélera les lignes de la même table.

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

Par exemple, nous voulons trouver les noms des employés dont la désignation initiale est égale à la désignation actuelle. Nous pouvons résoudre ce problème en utilisant l'auto-jointure de la manière suivante.

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

Un cas d'utilisation est la vérification des enregistrements en double dans une base de données.

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
1
Steven Stewart-Gallus

C'est l'équivalent de la base de données d'une liste/arborescence liée, où une ligne contient une référence en quelque sorte à une autre ligne.

0
Unsliced