PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 11/12/2020 15:42:21

Salomai
Membre

Problème d'insertion dans une table

Bonjour,

J'ai un petit soucis lors de mon insertion entre mes deux tables. J'ai une table employeur et une table contrat que j'alimente à partir d'une table générique "agro" qui contient l'intégralité des données (récupérées à partir d'un csv).

La table contrat contient une clé étrangère "employeur" reliée à la table employeur.

L'insertion de ma table employeur fonctionne parfaitement et celle de ma table contrat aussi : toutes les informations sont bonnes lorsque je fais des tests sur la table uniquement. Néanmoins, lorsque je fais des tests avec jointure des tables contrat et employeur les résultats obtenus sont bons mais incomplets (au lieu de me retourner 16 personnes qui ont travaillé dans les ONG par exemple, il m'en retourne que 7).

Je me dis que ce qui pêche ce doit être lors de l'insertion des valeurs dans la table contrat ... Voici ma requete d'insertion dans la table :

INSERT INTO "contrat"(pays, etudiant, employeur, fonction, type_contrat1, type_contrat2, annee_contrat, montant_salaire, secteur_niv1, secteur_niv2, temps_recherche, insertion)

SELECT pa."id", e."id", emp."id", f."id", inser_pro_type_contrat_niv1,
inser_pro_type_contrat_niv2, inser_pro_annee_contrat, inser_pro_salaire, inser_pro_secteur_activite_niv1, inser_pro_secteur_activite_niv2, inser_pro_temps_recherche_emploi, true

FROM "agro" as ag

LEFT JOIN "pays" pa ON pa.pays = ag.inser_pro_pays

INNER JOIN "etudiant" e ON e."id" = ag."id"

FULL JOIN "fonction" f ON f.fonction_niv1 = ag.inser_pro_fonction_niv1 AND f.fonction_niv2 = ag.inser_pro_fonction_niv2 AND f.intitule_exact = ag.inser_pro_fonction_intitule_exact AND f.statut = ag.inser_pro_statut

FULL JOIN employeur emp ON ag.inser_pro_organisme_nom = emp.nom_organisme AND ag.inser_pro_type_employeur_niv1 = emp.type_employeur_niv1 AND ag.inser_pro_type_employeur_niv2 = emp.type_employeur_niv2 AND ag.inser_pro_taille_structure_niv1 = emp.taille_structure_niv1 AND ag.inser_pro_taille_structure_niv2 = emp.taille_structure_niv2

WHERE (inser_pro_type_contrat_niv1 IS NOT NULL OR inser_pro_type_contrat_niv2 IS NOT NULL OR inser_pro_annee_contrat IS NOT NULL OR inser_pro_salaire IS NOT NULL OR inser_pro_secteur_activite_niv1 IS NOT NULL OR inser_pro_secteur_activite_niv2 IS NOT NULL OR inser_pro_temps_recherche_emploi IS NOT NULL);

pays, etudiant, employeur, fonction sont donc des clés étrangères ; les autres valeurs sont récupérées à partir de ma table agro.

Y aurait-il une erreur dans mon insertion que je ne vois pas ??

Merci de m'aider....

Bonne journée à vous!

Dernière modification par Salomai (11/12/2020 15:42:46)

Hors ligne

#2 14/12/2020 20:12:04

dverite
Membre

Re : Problème d'insertion dans une table

Pour donner une opinion sur la requête, il faudrait comprendre pourquoi elle utilise ces FULL JOIN, qui sont utilisés rarement dans ce contexte.
Avec ce type de jointure, quand on teste si une colonne est NULL on ne sait pas si la colonne est absente et mise à NULL par le FULL JOIN ou si elle est présente mais que sa valeur est effectivement à NULL. A moins que toutes ces colonnes soient déclarées NOT NULL dans la source.

Hors ligne

#3 15/12/2020 18:25:16

Salomai
Membre

Re : Problème d'insertion dans une table

Merci pour votre réponse.

Je ne suis pas super au clair avec les jointures je crois. En fait, j'ai créé la table employeur de manière à ce qu'il n'y ait aucune ligne de ma table entièrement nulle, ce qui fait qu'il y a moins de lignes que dans la table agro. J'ai procédé de la même manière pour la table fonction.
Bien que toutes les tables (contrat, fonction, employeur) aient des informations liées, le manque de données à disposition fait que j'ai parfois pour un étudiant aucune information dans la table fonction mais des infos dans la table contrat ou employeur. Ce pourquoi j'ai opté pour un FULL JOIN. Avec ce type de jointure, j'ai l'impression de ne perdre aucune informations mais par contre il est vrai qu'il y a beaucoup de NULL dans la table contrat.

J'espère avoir été claire...

Hors ligne

#4 28/12/2020 13:27:32

Salomai
Membre

Re : Problème d'insertion dans une table

Hm, après réflexion je pense que une jointure LEFT JOIN serait plus appropriée (car dans ma table employeur j'ai fait en sorte qu'il n'y ait aucune ligne nulle or il est possible - tellement la base est mal remplie - que j'ai l'information du contrat alors même que je n'ai pas d'employeur).

Après avoir inséré étape par étape dans la table contrat pour voir où se situait le problème, l'insertion bug effectivement à partir de fonction et d'employeur.

Est-ce que cela peut être lié au fait que parfois des lignes peuvent être les mêmes ? Du coup, lorsque je lui dit d'insérer quand employeur.col1 = agro.col1, employeur.col2 = agro.col2, etc., il se mélange les pinceaux ?

Je sais pas, au secours aidez-moi........................................

Hors ligne

#5 28/12/2020 20:09:42

dverite
Membre

Re : Problème d'insertion dans une table

Pour dire si le SQL est juste ou voir ce qui n'est pas juste, il faut revenir à l'expression ce que la requête doit faire.
Globalement on voit que la requête veut retrouver la ligne dans "fonction" qui satisferait ces conditions là:


f.fonction_niv1 = ag.inser_pro_fonction_niv1 AND f.fonction_niv2 = ag.inser_pro_fonction_niv2 AND f.intitule_exact = ag.inser_pro_fonction_intitule_exact AND f.statut = ag.inser_pro_statut

sachant que "ag" désigne la table "agro" et f la table "fonction"


Et il y a la même logique pour la table employeur, avec ces conditions là:

ag.inser_pro_organisme_nom = emp.nom_organisme AND ag.inser_pro_type_employeur_niv1 = emp.type_employeur_niv1 AND ag.inser_pro_type_employeur_niv2 = emp.type_employeur_niv2 AND ag.inser_pro_taille_structure_niv1 = emp.taille_structure_niv1 AND ag.inser_pro_taille_structure_niv2 = emp.taille_structure_niv2

Pour que cette logique fonctionne, il y a déjà des choses à vérifier:

- est-ce que certaines de ces colonnes dans agro peuvent être à NULL ou pas?


- si oui, est-ce que la colonne correspondante dans employeur ou fonction doit être NULL quand la colonne dans agro s'avère être à NULL? Autrement dit est-ce que NULL d'un côté et NULL de l'autre doit être considéré comme une égalité ou au contraire dès que l'un des côtés est NULL la correspondance ne doit pas être détectée?

Dans les réponses plus haut il est dit que dans la table employeur, une ligne ne peut pas être complètement nulle. Mais ce n'est pas la même question, parce que la condition de jointure ci-dessus est fausse dès qu'une seule colonne est à NULL.


- quand on a une correspondance sur toutes ces colonnes, quelle est la garantie qu'il y a une seule ligne qui correspond dans fonction (resp. employeur) ? Autrement dit est-ce qu'il y a un index unique (clef composite) sur l'ensemble de ces colonnes? S'il peut y avoir plusieurs lignes correspondantes, ça va poser un problème de multiplication des lignes à insérer.

Hors ligne

#6 29/12/2020 20:28:27

Salomai
Membre

Re : Problème d'insertion dans une table

Merci pour votre réponse.

Les lignes de employeur & fonction ne peuvent pas être nulles, par contre une colonne peut être nulle.
J'aimerais une jointure qui accepte les lignes nulles de la table agro car, comme je l'ai dit, la base étant tellement mal remplie, je peux avoir les informations associées aux contrats mais pas à l'employeur. C'est pour ça que je pensais un LEFT JOIN adapté, mais je me trompe peut-être....?


Pour votre dernier point : "quand on a une correspondance sur toutes ces colonnes, quelle est la garantie qu'il y a une seule ligne qui correspond dans fonction (resp. employeur) ? Autrement dit est-ce qu'il y a un index unique (clef composite) sur l'ensemble de ces colonnes? S'il peut y avoir plusieurs lignes correspondantes, ça va poser un problème de multiplication des lignes à insérer."
Effectivement, ça risque de poser problème car il n'y a pas la garantie d'unicité pour les lignes... Mais comment rajouter un index unique pour éviter la multiplication des lignes à insérer ?

Hors ligne

#7 04/01/2021 19:16:23

Salomai
Membre

Re : Problème d'insertion dans une table

Pourquoi : "la condition de jointure ci-dessus est fausse dès qu'une seule colonne est à NULL" ?

Hors ligne

#8 04/01/2021 22:13:05

dverite
Membre

Re : Problème d'insertion dans une table

Parce que dans la comparaison NULL=quelquechose, NULL est absorbant, comme 0 dans la multiplication,
et que dans une combinaison logique expr1 AND expr2,  NULL comme expression est aussi absorbant.

dit en SQL

test=> select ( true AND true AND 1=null ) is true;
 ?column? 
----------
 f

Concrètement pour la jointure ça veut simplement dire que dans l'appariemment avec par exemple la table "fonction", si une des colonnes relatives à la fonction dans la table d'import est nulle, peu importe les autres colonnes, le résultat de l'appariemment avec LEFT JOIN est qu'il n'y aura pas de ligne trouvée dans fonction. Si c'est le résultat attendu, pas de problème.

Hors ligne

#9 07/01/2021 14:34:52

Salomai
Membre

Re : Problème d'insertion dans une table

Effectivement c'est ce qui pose problème pour la table fonction !!

Comment forcer l'insertion des colonnes nulles sur postgres ??

Hors ligne

#10 07/01/2021 16:58:25

dverite
Membre

Re : Problème d'insertion dans une table

Pour ce que je comprends, vous avez une table fonction d'un côté qui préexiste (la question ne porte pas sur comment remplir cette table), avec une colonne "id" qui est une clef synthétique sans signification métier, et des colonnes

fonction_niv1
fonction_niv2
intitule_exact
statut

qui ont des significations métier.


D'un autre côté il y a un import dans une table agro avec 4 colonnes ci-dessous qui correspondent dans le même ordre:

inser_pro_fonction_niv1
inser_pro_fonction_niv2
inser_pro_fonction_intitule_exact
inser_pro_statut

sauf que cette correspondance peut être imparfaite, parce que sinon une jointure simple sur l'ensemble des colonnes fonctionnerait.


A mon sens si c'est bien la situation de départ, vous ne pouvez pas faire l'économie de décrire dans le détail, au niveau métier, ce qui est acceptable ou pas pour établir la correspondance entre une ligne à importer et les valeurs dans la table fonction.

C'est seulement une fois que l'analyse métier est faite, qui prend en compte tous les cas possibles, qu'on peut écrire le bout de SQL (LEFT JOIN ou autre) qui met en oeuvre cette analyse.

En l'occurrence les cas possibles semblent être des réponses oui/non aux quetsions "telle colonne est-elle remplie?" puisque si elle est remplie c'est une correspondance exacte sur la valeur qui va être attendue (je suppose).

Mais avec 4 colonnes ça fait quand même 2^4=16 combinaisons d'un côté de la jointure, 16 combinaisons de l'autre, soit 16x16=256 combinaisons possibles.

Hors ligne

Pied de page des forums