Galère de LEFT JOIN [Résolu/Fermé]

Signaler
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020
-
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020
-
Bonsoir,

Souci avec un LEFT JOIN quand trois tables sont impliquées.

. Soit une propriété en ville composée de 3 corps de batiments (A, B, C).
. Chaque batiment contient 6 étages. A chaque étage, il y a 4 appartements (D, FD, FG, G pour Droite, Face Droit, Face Gauche, Gauche)

C'est arrivé qu'une même personne reste dans la propriété mais change de bâtiment.
Elle apparait donc plusieurs fois dans la relation Personne-Habiter-Appartement. => relation n-aire. Le schema et les tables sont donc les suivants (identifiants - clefs primaires, soulignés)
Personne--1,n----Habiter----0,n--Appartement

Personnes(idpers, nom, prénom, etc...)
Habiter(idpers,idapt,debut,fin)
Appartements(idapt,batiment,etage,position,type)

Personnes :
+---+--------+----------+-----+
| 1 | DUPONT | Marcel   | ... |
| 2 | DUVAL  | Isabelle | ... |

Habiter :
+----+----+------------+------------+
|  2 |  9 | 1998-03-29 | 2007-31-08 |
| 42 | 12 | 2015-07-28 | 0000-00-00 |

Appartements :
+----+---+---+----+--------+
|  9 | A | 3 | FG | F3     |
| 10 | A | 3 |  G | F5     |
| .. | . | . | .. | ...... |
| 25 | C | 6 |  D | Studio |

J'aimerais sortir la liste de TOUS les appartements, occupés ou non et s'ils sont occupés, le nom du locataire en regard. ex :

mysql> SELECT ....
+----+---+---+----+--------+--------+----------+
|  9 | A | 3 | FG | F3     | DUPONT | Marcel   |
| 10 | A | 3 |  G | F5     | NULL   | NULL     |
| 25 | C | 6 |  D | Studio | DUVAL  | Isabelle |


J'arrive très bien avec une relation une-aire (deux tables, pas de table Habiter et idapt migré dans la table Personnes) avec un left join et deux tables mais je m'emmêle les pinceaux avec trois tables.

Merci de votre aide...


Configuration: Dual boot: Windows XP Pro SP3 / Debian Linux

1 réponse

Messages postés
12725
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
22 octobre 2020
707
bonjour, s'agit-il d'un travail solaire?
peux-tu partager la relation à laquelle tu arrives très bien?
qu'as-tu essayé avec les trois tables?
je suis surpris que tu indiques que Marcel Dupont occupe un appartement: pourquoi indiques-tu cela?
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020
101
Bonsoir,

merci pour ta réponse.

La solution initiale était celle-ci : Relation une-aire à cause des cardinalités Personnes (1,1) : Une personne ne participe qu'une fois et une seule à la relation Habiter (en effet, n'ayant pas le don d'ubiquité, elle ne loge que dans un appartement et un seul). (Souligné = ID, clef primaire ; Italique = clef étrangère)
Personne--1,1----Habiter----0,n--Appartement

Personnes(idpers, nom, prénom, idapt, etc...)
Appartements(idapt,batiment,etage,position,type)


Personnes :
+---+--------+----------+----+-----+
| 1 | DUPONT | Marcel   | 10 | ... |
| 2 | DUVAL  | Isabelle | 25 | ... |

Appartements :
+----+---+---+----+--------+
|  9 | A | 3 | FG | F3     |
| 10 | A | 3 |  G | F5     |
| .. | . | . | .. | ...... |
| 25 | C | 6 |  D | Studio |


La requete qui fonctionnait était :
SELECT `batiment`,`etage`,`position`,`type`,`idpers`,`nom`,`prenom`
FROM Appartements LEFT JOIN Personnes ON Appartements.idapt=Personnes.idapt
ORDER BY `batiment`,`etage` desc,`position`,`nom`,`prenom`;


Mais étant donné qu'un locataire peut pour des raisons de travaux quitter un appartement pour en occuper un autre dans la même propriété, un locataire peut donc participer 1 ou plusieurs fois (1,n) à la relation Habiter. d'où changement de modèle pour en arriver au modèle que j'ai posté en question. Et là, il y a maintenant trois tables puisque la relation n-aire (toutes les cmax à n) donnent lieu à la création de la table Habiter. Et là, je coince avec les LEFT JOIN avec trois tables. Je crois savoir (mais je n'en suis pas sûr qu'on peut faire un LEFT JOIN avec le résultat d'une requête (genre: Appartements LEFT JOIN avec le résultat d'une requête incluant Personnes et Habiter) Mais là je pense nager... D'où mon Help !

Ai-je été clair dans la définition du problème ?

PS: Pour DUPONT Marcel, tu as bien vu, c'etait une erreur de ma part. La table Habiter était :

Habiter :
+----+----+------------+------------+
|  1 |  9 | 1998-03-29 | 2007-31-08 |
| 42 | 12 | 2015-07-28 | 0000-00-00 |
Messages postés
12725
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
22 octobre 2020
707 >
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020

peut-être:
SELECT `batiment`,`etage`,`position`,`type`, Habiter.idpers, `nom`,`prenom`
FROM Appartements 
LEFT JOIN Habiter ON Appartements.idapt=Habiter.idapt AND ...condition sur les dates...
LEFT JOIN Personnes ON Habiter.idapt=Personnes.idapt
ORDER BY `batiment`,`etage` desc,`position`,`nom`,`prenom`;
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020
101
Merci infiniment, C'est tout-à-fait la requête qui convient :

SELECT `batiment` as bat,`etage`,`position` as pos,`type`,`nom`,`prenom`
FROM Appartements
LEFT JOIN Habiter ON Appartements.idapt=Habiter.idapt
LEFT JOIN Personnes ON Habiter.idpers=Personnes.idpers AND `statut`='P'
ORDER BY `batiment`,`etage` desc,`position`,`nom`,`prenom`;

Personnes.statut
pouvant être P (Particulier) ou S (Société). Voici ce que ça donne :

+-----+-------+-----+--------+---------------------------+-----------------+
| bat | etage | pos | type   | nom                       | prenom          |
+-----+-------+-----+--------+---------------------------+-----------------+
| B   |     2 | D   | F2     | BARJAVEL                  | Jonas           |
| B   |     2 | FD  | F4     | BONNIMARRON               | Stéphanie       |
| B   |     2 | FD  | F4     | GUASTON                   | Freddy          |
| B   |     2 | FG  | F2     | NULL                      | NULL            |
| B   |     2 | G   | F2     | NULL                      | NULL            |
| B   |     1 | D   | F3     | NULL                      | NULL            |
| B   |     1 | FD  | F4     | TORDJMANN                 | Marceau         |
| B   |     1 | FD  | F4     | TORDJMANN                 | Johanne         |
| B   |     1 | FG  | F5     | DE VALLUIS DE TAILLERAULT | Anne-Sophie     |
| B   |     1 | FG  | F5     | MILLET                    | Jean            |
| B   |     1 | G   | Studio | NULL                      | NULL            |
| B   |     0 | D   | F2     | NULL                      | NULL            |
| B   |     0 | G   | F3     | DE MONTOLBIERE            | Marianne        |
etc...

Je ne savais pas que l'on pouvait "enquiller" les LEFT JOIN les uns après les autres. Merci.
Je viendrai fermer le fil dans un jour ou deux, juste pour me laisser le temps d'une autre tentative (utiliser le résultat d'une requête entre deux tables, comme une table) dans le genre :

FROM table1, (résultat requête)
WHERE ...

Il me semble avoir vu ça quelque part...

Si je trouve, je viens poster le résultat et je ferme. Si je ne trouve pas, je ferme aussi.

En tout cas, merci beaucoup.

PS: Non, ce n'est pas un travail scolaire mais un projet de site web d'information et de communication entre les résidents d'une même propriété sans vouloir concurrencer Nextdoor qui, comme la plupart des réseaux sociaux, collecte les informations ; mais justement les protège d'une collecte de données. On échange entre nous, sans cookies, sans traqueurs, etc...
Messages postés
12725
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
22 octobre 2020
707 >
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020

je pense utile d'ajouter les conditions sur les dates
Messages postés
468
Date d'inscription
mardi 1 juillet 2008
Statut
Membre
Dernière intervention
9 juillet 2020
101
Juste ! N'afficher que les résidents pour lesquels la date de fin est égale à "0000-00-00" (ceux qui habitent encore là, pour lesquels il n'y a pas encore de date de fin).
Ou si l'on veut les locataires ayant quitté leur logement, ceux dont la date de fin est différente de "0000-00-00".
Merci pour cette précision.