Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1256 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Problème de clé étrangère [RESOLU]

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème de clé étrangère [RESOLU]

n°1894217
Profil sup​primé
Posté le 11-06-2009 à 16:25:53  answer
 

Bonjour  [:maxmaker] ,
 
J'ai un problème avec une requête SQL. Je voudrais avoir un résultat qui nécessite de passer par 2 tables et donc d'avoir une clé étrangère.
 
Présentation de mes tables.
 

CREATE TABLE utilisateur  
(
  id_util int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  nom_util varchar(20) NOT NULL,
  prenom_util varchar(20) NOT NULL,
  login varchar(20) NOT NULL,
  pass varchar(20) NOT NULL,
  statut varchar(25) NOT NULL,
  FOREIGN KEY (statut) REFERENCES statut (id_statut)
);



CREATE TABLE statut
(
  id_statut int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  intitule_statut varchar(20) NOT NULL
);


Ma requête est toute simple  [:getalife]  
 


SELECT nom_util, prenom_util, intitule_statut
FROM statut, utilisateur
WHERE utilisateur.statut = statut.id_statut;


 
Quand je fais ça dans PhpMyAdmin la requête ne me renvois aucun résultat alors que ces colonnes sont remplis.
Y aurait-il une explication toute simple et logique à ce mystérieux problème qui m'empêche de dormir ?  [:doc petrus]  
 
Merci  [:pseudoman]


Message édité par Profil supprimé le 16-06-2009 à 11:05:02
mood
Publicité
Posté le 11-06-2009 à 16:25:53  profilanswer
 

n°1894235
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 11-06-2009 à 17:36:31  profilanswer
 

D'un coté le champ "statut" de ta table "utilisateur" est un varchar de longueur 25, et de l'autre le champ id_statut de ta table "statut" est un int de longueur 11.
Sachant que l'un est une clé étrangère de l'autre, tu n'as pas l'impression d'une petite incohérence là ?


---------------
J'ai un string dans l'array (Paris Hilton)
n°1894238
olivthill
Posté le 11-06-2009 à 17:39:31  profilanswer
 

Le problème est que la jointure est faîte sur des données qui ne sont pas de même type :
utilisateur.statut est un varchar2, alors que statut.id_statut est un entier. Il faudrait juste rajouter une fonction de conversion. En Oracle, on ferait WHERE utilisateur.statut = to_char(statut.id_statut); ou WHERE to_number(utilisateur.statut) = statut.id_statut;. Mais je ne connais pas la syntaxe MySQL par coeur.

n°1894239
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 11-06-2009 à 17:40:43  profilanswer
 

olivthill a écrit :

Le problème est que la jointure est faîte sur des données qui ne sont pas de même type :
utilisateur.statut est un varchar2, alors que statut.id_statut est un entier. Il faudrait juste rajouter une fonction de conversion. En Oracle, on ferait WHERE utilisateur.statut = to_char(statut.id_statut); ou WHERE to_number(utilisateur.statut) = statut.id_statut;. Mais je ne connais pas la syntaxe MySQL par coeur.


Il faudrait surtout qu'il mette les mêmes types sur les 2 champs !


---------------
J'ai un string dans l'array (Paris Hilton)
n°1894248
Profil sup​primé
Posté le 11-06-2009 à 18:51:19  answer
 

Ah oui exact, je viens de rectifier ça. Par contre PhPMyadmin m'indique toujours 0 résultat.

n°1894271
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 11-06-2009 à 21:05:23  profilanswer
 

Et avec une jointure externe, tu obtiens des résultats ?


---------------
J'ai un string dans l'array (Paris Hilton)
n°1894272
Profil sup​primé
Posté le 11-06-2009 à 21:17:31  answer
 

Je...sais pas faire de jointures externe  :sweat:  
 
J'vais voir la tronche que ça a.

n°1894298
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 11-06-2009 à 22:40:53  profilanswer
 

LEFT JOIN
D'ailleurs tu devrais employer la syntaxe INNER JOIN au lieu de faire des jointures "à l'ancienne" avec WHERE, c'est plus correct


---------------
J'ai un string dans l'array (Paris Hilton)
n°1894380
Profil sup​primé
Posté le 12-06-2009 à 10:47:18  answer
 

Alors, j'ai essayé avec INNER JOIN et il m'envoie sur les roses, j'ai aussi essayé en changeant le moteur MyISAM par InnoDB mais rien n'y fait.
Par contre j'ai pas essayé avec LEFT JOIN.
 
 
 :sweat:

n°1894397
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 12-06-2009 à 11:22:36  profilanswer
 

Comment ça le "INNER JOIN m'envoie sur les roses" ? C'est quoi le message d'erreur ? Tu as utilisé la bonne syntaxe ?

Code :
  1. SELECT nom_util, prenom_util, intitule_statut
  2. FROM statut LEFT JOIN utilisateur ON utilisateur.statut = statut.id_statut


ça donne quoi ?


Message édité par Harkonnen le 12-06-2009 à 11:23:26

---------------
J'ai un string dans l'array (Paris Hilton)
mood
Publicité
Posté le 12-06-2009 à 11:22:36  profilanswer
 

n°1894400
Profil sup​primé
Posté le 12-06-2009 à 11:30:24  answer
 

Ah ça marche presque. En fait au lieu de m'afficher nom_util et prenom_util ça me met des NULL (alors que c'est rempli pourtant), en revanche l'intitule s'affiche bien.


Message édité par Profil supprimé le 12-06-2009 à 11:30:53
n°1894404
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 12-06-2009 à 11:35:10  profilanswer
 

Oui mais c'est normal que ça mette des NULL, le LEFT JOIN affiche toutes les données de la table de gauche (donc la table statut dans ton cas), même si elles ne sont pas remplies, alors que le INNER n'affiche que les données existantes. Je te l'ai fait faire pour justement vérifier si ta table comportait des données.

 

Donc si tu as des NULL, ça veut dire que ta table statut ne contient rien du tout par rapport à ton critère de jointure... Et c'est pour ça que ton INNER JOIN foire.


Message édité par Harkonnen le 12-06-2009 à 11:43:45

---------------
J'ai un string dans l'array (Paris Hilton)
n°1894558
Profil sup​primé
Posté le 12-06-2009 à 15:57:28  answer
 

J'ai encore un peu de mal avec cette nouvelle syntaxe puisque au lycée on nous apprends a travailler uniquement avec le WHERE.
Et j'ai bien regardé le nom de mes champs et leu contenu et rien n'est vide, comment ça se fait  :??:

Message cité 1 fois
Message édité par Profil supprimé le 12-06-2009 à 16:04:04
n°1894573
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 12-06-2009 à 16:13:43  profilanswer
 


Et bien ton lycée à tout faux !
Le WHERE sert à filtrer une requête, pas à faire une jointure. Il faut savoir que cette syntaxe date de 1986, il serait temps d'évoluer.
L'avantage de la syntaxe avec INNER est multiple :
- ça permet de bien distinguer la partie de la requête qui concerne la jointure de la partie qui fait partie du filtre. Quand tu as une grosse requête sur plusieurs tables avec plein de clauses WHERE, ça devient vite chiant de décortiquer la requête pour trouver les WHERE qui concernent la jointure et les WHERE qui font partie du filtre. Avec JOIN, pas d'ambiguité possible
- imagine la requête suivante :

Code :
  1. SELECT a, b, c, d, e
  2. FROM toto, tata, tutu, titi
  3. WHERE toto.xxx = 3
  4. AND toto.yyy > 9
  5. AND titi.uuu != NULL
  6. AND tata.fff = 'kikoo lol asv ?'
  7. AND toto.id = tata.id
  8. AND tata.id = tutu.id
  9. AND titi.id = toto.id


Maintenant, tu te rends compte que ta requête ne donne pas les résultats escomptés. Tu choisis de débugger en virant une clause WHERE. Mais tu te plantes et tu vires la ligne "AND tata.id = tutu.id".
Résultat : plus de jointure entre tata et tutu. Tu lances ta requête, et comme il n'y a plus de jointure entre ces tables, tu te retrouves avec un produit cartésien entre tata et tutu, qui peut mettre ton serveur à genoux si ces tables contiennent plusieurs milliers d'enregistrements.
Le WHERE pour les jointures, c'est le mal. Les profs qui enseignent ça devraient bruler en enfer.

 

Quant à ton problème, difficile de t'aider sans la base sous les yeux.


Message édité par Harkonnen le 12-06-2009 à 16:14:18

---------------
J'ai un string dans l'array (Paris Hilton)
n°1894589
Profil sup​primé
Posté le 12-06-2009 à 16:35:03  answer
 

Merci pour l'exemple, ça permet en effet de mieux se rendre compte, et je maintiens que notre prof de SQL ne nous a jamais mentionné l'existence de INNER et LEFT JOIN  :sweat:  
 
Sinon pour mon soucis tout est réglé  ;)  Il y avait une mauvaise incrémentation d'un champ ce qui faisait tout capoter  :)  
 
Encore merci pour le coup de main et la leçon sur le INNER  
 
 :hello:

n°1895581
Profil sup​primé
Posté le 16-06-2009 à 10:54:41  answer
 

Un ptit up pour une nouvelle question  :)  
 
J'ai deux tables Materiel(id_materiel, etat_materiel) et une table Type(id_type, type_machine, marque, #num_mat)
 
J'aimerai afficher uniquement les machines qui sont de type 'ordinateur'. Donc je fais la requête suivante.
 
SELECT id_materiel,etat_materiel,marque,description_type  
FROM materiel  
LEFT JOIN type  
ON type.num_mat = materiel.id_materiel
AND type_machine = 'ordinateur'
ORDER BY id_materiel;
 
Le problème c'est que la requête m'affiche quand même l'id_materiel et etat_materiel des machines qui ne sont pas des ordinateurs.
 
J'ai du mal à voir comment je pourrais corriger ça  :sweat:  
 
Merci

n°1895585
Deamon
Posté le 16-06-2009 à 11:01:05  profilanswer
 

WHERE type_machine = 'ordinateur'  
 
car c'est un filtre ça, pas une jointure

n°1895588
Profil sup​primé
Posté le 16-06-2009 à 11:04:39  answer
 

Ah oui exact. Merci beaucoup.
 
Ça va finir par rentrer un jour, si si  :o

n°1895589
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 16-06-2009 à 11:05:36  profilanswer
 

Voilà, c'est exactement ce que je disais... A force de faire des jointures avec des WHERE, on finit par ne plus distinguer ce qui est jointure et ce qui est filtre... Les profs qui enseignent de cette façon méritent la peine de mort :sarcastic:


---------------
J'ai un string dans l'array (Paris Hilton)
n°1895602
Profil sup​primé
Posté le 16-06-2009 à 11:20:05  answer
 

Exactement, mauvaise habitude  :sweat:  Mais bon je vais corriger ça, merci à vous deux  :jap:

n°1896114
MagicBuzz
Posté le 17-06-2009 à 10:42:38  profilanswer
 

Deamon a écrit :

WHERE type_machine = 'ordinateur'  
 
car c'est un filtre ça, pas une jointure


d'ailleurs, ça c'est un des points positifs d'ACCESS sur les autres SGBD : sur ce point il est bien plus rigoureux que les autres, puisqu'il plante si on met un filtre dans une clause "ON".
 
sympa pour prendre en main la syntaxe du coup

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Problème de clé étrangère [RESOLU]

 

Sujets relatifs
[résolu] parcours d'un char** sans connaitre le nombre de chainesDésactiver automatiquement des checkbox si on en coche 1 autre[RESOLU]
Problème Libraires VBA Accessprobleme a l'upload d'image ...
[PERL] Problème d'espace avec glob()Problème de connection FREE à SQL.FREE.FR ?? Mystère!
Syntaxe étrange en C++ avec GCC (résolu)[Résolu] Plusieurs argument dans une url fonction js ajax
Problème de paramètre dans ma fonction[Resolu]API MYSQL erreur compilation
Plus de sujets relatifs à : Problème de clé étrangère [RESOLU]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR