Requête SQL généalogique

Résolu
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 - 9 juin 2023 à 01:47
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 - 17 juin 2023 à 00:44

Bonsoir,

Je me prends la tête depuis 3 jours sur une requête SQL qui me paraît complexe.
Il s'agit d'une base de données généalogiques dans laquelle il y a plusieurs tables, dont :

gen_People (idpers,lname,fname,...,bplac,dplac,...) # Table des personnes

idpers : identifiant de la personne
lname  : last name
fname  : first name
bplac  : birth place
dplac  : death place
...    : autres champs

Exemple :
|  47 | DUPONT   | Marc     | Bordeaux   | Toulouse   | ...

gen_Marry (idfam,idh,idw,...,uplac,...) # Table des unions

idfam : identifiant de la famille
idh   : ID husband (idpers du mari)
idw   : ID wife (idpers de la femme)
uplac : Union place
...   : autres champs

Exemple :
| 32 |  134 |  48 | Sydney   | ...

Objectif de la requête : une recherche.
Un formulaire demande à saisir une chaîne de caractères. si cette chaîne se trouve dans un nom, un prénom, un lieu de naissance, de décès ou d'union : sortir les individus concernés.

S'il ne fallait trouver que les personnes d'un couple répondant aux conditions, ça irait. Mais il y a des enfants, non mariés, nés dans certains lieux et qui ne figurent pas ni en tant que idh, ni en tant que idw dans la table gen_Marry mais qu'il faut quand même trouver si leurs lieux de naissance correspondent au critère recherché.

Voici ma requête  (chaîne recherchée = sydney):

SELECT gen_People.idpers, gen_People.lname, gen_People.fname
FROM gen_People, gen_Marry
LEFT JOIN gen_People AS wife ON wife.idpers=gen_Marry.idw
WHERE gen_People.idpers=gen_Marry.idh
AND (gen_People.lname like '%sydney%'
OR gen_People.fname like '%sydney%'
OR gen_People.bplac like '%sydney%'
OR gen_People.dplac like '%sydney%'
OR uplac like '%sydney%')
ORDER BY gen_People.fname,gen_People.lname;

Quatre personnes sont normalement concernées :
-- 308, TCHONG Bui (décédé à Sydney)
-- 57, DUPONT Guillaume (gendre de 308, père de 62 et 589 ci-dessous, et marié à Sydney)
-- 62, DUPONT Loïc (enfant né à Sydney)
-- 589, DUPONT Arthur (enfant né à Sydney)

La requête ci-dessus ne me trouve que :
-- 308, TCHONG Bui
-- 57, DUPONT Guillaume
deux personnes mariées mais pas les enfants (ID non présents dans gen_Marry).

NB: Il n'est pas obligatoire de sortir les deux noms, par exemple le mari ET la femme s'ils se sont mariés à Sydney. L'un ou l'autre suffira car en cliquant sur l'un ou l'autre des deux on fera apparaître sa fiche mentionnant son mariage à Sydney (si sydney est l'objet de la recherche). En revanche il faudra sortir les deux personnes du couple si le critère de recherche est trouvé dans les noms ou les prénoms (Jean-Paul et Marie-Paule avec 'paul' comme recherche).

Si quelqu'un a une idée, je suis preneur. Merci par avance...

Windows / Firefox 113.0


2 réponses

jee pee Messages postés 39743 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 18 mai 2024 9 191
Modifié le 9 juin 2023 à 08:14

Bonjour,

Si non mariés, ils ne sont pas dans la table gen_Marry, cette table alors ne devrait pas être dans le FROM, mais dans une jointure externe, pour ramener l'enregistrement gen_People même même s'il n'a pas de correspondance dans gen_Marry.

Par ailleurs à quoi sert l'alias Wife puisque la requête n'utilise aucune des données de cette seconde occurrence de la table gen_People ?


1
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 137
17 juin 2023 à 00:44

Merci pour ta réponse efficace. Effectivement l'alias wife ne se justifie pas car mari ou femme sont tous les deux dans gen_People. Donc :

SELECT ...
FROM gen_People
LEFT JOIN gen_Marry ON
(gen_People.idpers=gen_Marry.idh OR gen_People.idpers=gen_Marry.idw)
WHERE ... (critère de recherche) ...
ORDER BY ...

J'ai testé. Sur 883 personnes dans gen_People et 256 familles (couples) dans gen_Marry, les 5 identifiés sont sortis. Je pensais 4, mais en fait c'est 5 : 3 + un couple (donc +mari, +femme mariés au même endroit :-) = 5.

Je vais mettre ça au propre sous PHP et ce sera bon.

Je te remercie infiniment.

1
yg_be Messages postés 22793 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 18 mai 2024 1 467
10 juin 2023 à 09:47

bonjour, suggestion:

SELECT gen_People.idpers, gen_People.lname, gen_People.fname
FROM gen_People
WHERE  gen_People.lname like '%sydney%'
OR gen_People.fname like '%sydney%'
OR gen_People.bplac like '%sydney%'
OR gen_People.dplac like '%sydney%'
UNION
SELECT gen_People.idpers, gen_People.lname, gen_People.fname
FROM gen_People, gen_Marry
WHERE (gen_People.idpers=gen_Marry.idh
OR gen_People.idpers=gen_Marry.idw)
AND gen_Marry.uplac like '%sydney%'
0