Page 1 sur 2

Requete sql sur 3 tables liés

Posté : 18 janv. 2008, 12:55
par newby
Bonjour ,je viens de me lancer dans l'etude des tables liés afin d' "essayer de progresse"'.
J'utilise la sgbd mysql.

je viens de crer 3 tables qui sont les suivantes:

Code : Tout sélectionner

REATE TABLE `enumereintituleprestation` ( `idIntitule` tinyint(20) NOT NULL auto_increment, `NomIntitule` text NOT NULL, `DeignationIntitule` text NOT NULL, PRIMARY KEY (`idIntitule`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ; -- -- Contenu de la table `enumereintituleprestation` -- INSERT INTO `enumereintituleprestation` (`idIntitule`, `NomIntitule`, `DeignationIntitule`) VALUES (1, 'Forfait 1', 'Carrez, Amiante, Termites, DPE et ERNT.'), (2, 'Forfait 2', 'Carrez, Amiante, Termites, DPE, ERNT et Gaz.'), (3, 'Forfait 3', 'Carrez, Amiante, Termites, DPE, ERNT, Gaz et Plomb.'), (4, 'Amiante', 'Repèrage des matériaux et produits susceptibles de contenir de l''amiante'), (5, 'Carrez', 'Certificat de superficie privative'), (6, 'Dpe', 'Diagnostic de performance energétique'), (7, 'Gaz', 'Constat des risques d''exposition au gaz'), (8, 'Ptz', 'Prêt à taux Zéro ou Norme de surface et d''habitabilité'), (9, 'Crep', 'Constat des risques d''exposition au plomb'), (10, 'Termite', 'Diagnostic termites et autres insectes xylophages'), (11, 'Electricite', 'Vérification des normes de votr einstallation electrique'), (12, 'Ernt', 'Etat des risques naturels et technologiques');

Code : Tout sélectionner

CREATE TABLE `enumerenbrepiece` ( `idPiece` tinyint(1) NOT NULL auto_increment, `TitrePiece` text NOT NULL, PRIMARY KEY (`idPiece`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; -- -- Contenu de la table `enumerenbrepiece` -- INSERT INTO `enumerenbrepiece` (`idPiece`, `TitrePiece`) VALUES (1, 'F1'), (2, 'F2'), (3, 'F3'), (4, 'F4'), (5, 'F5'), (6, 'Maison');

Code : Tout sélectionner

CREATE TABLE `enumereprixforfait1` ( `id` int(6) NOT NULL auto_increment, `idIntitule` tinyint(3) NOT NULL, `idPiece` tinyint(3) NOT NULL, `PrixTtc` float NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; -- -- Contenu de la table `enumereprixforfait1` -- INSERT INTO `enumereprixforfait1` (`id`, `idIntitule`, `idPiece`, `PrixTtc`) VALUES (1, 1, 1, 264), (2, 1, 2, 280), (3, 1, 3, 298), (4, 1, 4, 315), (5, 1, 5, 332), (6, 1, 6, 432);
deja premier point de forme , ne ferais je pas mieux d'inverser les noms des colonnes quand je reutilise l'identifiant qui proveint du autre table ce qui me donnerait dans le cas de ma derniere table par exemple

enumereprixforfait1
id,IntituleId,PieceId,PrixTtc

deuxieme point:
l'utilisateur va choisir dans un formulaire le nombre de piece a partir d'un menu deroulant et le type de prestation qu'il veut que l'on realise .le type de prestation etant caractérisé par un Nom et une designation le tout present dans ma table enumereintituleprestation donc j'ai pensais a une requete suivante:

Code : Tout sélectionner

SELECT enumereinituleprestation.NomIntitule,enumereintituleprestation.DesignationIntitule,enumereprixforfait1.PrixTtc FROM enumereintituleprestation,enumerenbrepiece,enumereprixforfait1 WHERE enumereprixforfait1.idPiece='".$_POST['NbrePIeceSelectionneParFormulaire']."' AND enumereintituleprestation.NomInituleprestation='"..$_POST['NbreDePrestationSelectionneParFormulaire']."' ";
troisiement ,j'utilise une base de donnée mysql donc je j'utiliserai par fonction mysql_query poour envoyer me requete ,mais quelle est la fonction qui me permettra de recuperer mes enregistrement correspondant??et comment les afficher par la suite .

Merfi d'avance de vos conseils avisagés.[/code]

Posté : 18 janv. 2008, 13:00
par Berzemus
Déjà, tu peux renommer tes tableaux (et tes colonnes) dans ta requête, en direct.

Du coup, ça donne environ ça;

Code : Tout sélectionner

SELECT A.NomIntitule as NomIntitule, A.DesignationIntitule as DesignationIntitule,C.PrixTtc as PrixTtc FROM enumereintituleprestation as A,enumerenbrepiece as B,enumereprixforfait1 as C WHERE C.idPiece='".$_POST['NbrePIeceSelectionneParFormulaire']."' AND A.NomInituleprestation='".$_POST['NbreDePrestationSelectionneParFormulaire']."' ";
ça reste quand même un peu verbeux..

Il te faudrait un JOIN entre A et C, mais je ne vois pas à quoi correspond B ? pourquoi l'avoir inclus ?

Posté : 18 janv. 2008, 15:14
par newby
en fait a la base ces trois tables etaient reunies en une seule de la forme suivante:

Code : Tout sélectionner

CREATE TABLE `enumereprixaormule1` ( `id` int(6) NOT NULL auto_increment, `Reference` text NOT NULL, `Designation` text NOT NULL, `NbrePiece` varchar(10) NOT NULL, `PrixTtc` float NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; -- -- Contenu de la table `enumereprixformule1` -- INSERT INTO `enumereprixformulae1` (`id`, `Reference`, `Designation`, `NbrePiece`, `PrixTtc`) VALUES (1, 'Amiante', 'Repérage des produits et matériaux susceptibles de contenir de l''amiante', 'F1', 30), (2, 'Amiante', 'Repérage des produits et matériaux susceptibles de contenir de l''amiante', 'F2', 40), (3, 'Amiante', 'Reperage des produits et materiaux susceptibles de contenir de l''amiante', 'F3', 50), (4, 'Amiante', 'Reperage des produits et materiaux susceptibles de contenir de l''amiante', 'F4', 60), (5, 'Amiante', 'Reperage des produits et materiaux susceptibles de contenir de l''amiante', 'F5', 70), (6, 'Amiante', 'Reperage des produits et materiaux susceptibles de contenir de l''amiante', 'Maison', 70);
et ma requete etait tout simplmetn la suivante:

Code : Tout sélectionner

SELECT Reference,Designation,PrixHt,PrixTtc from `enumereprixformule1` WHERE NbrePiece='".$_POST['nbrepiecebien']."'";
je me suis un peu embrouikillé l'esprit avec les tables liés et je pensais que je devais recupéré avec le AND quelque chose alors que ce n'est pas tuile.

peut tu m'en dire plus sur la facon dont tu renommes les tables et tes histoires de A B C et as car sur le site l'altruiste.com ,il part directement des requetes complexes !!
d'avance merci de ta part.[/code]

Posté : 18 janv. 2008, 15:28
par newbie
je viens de comprendre pourquoi tu me demandais ce que venais faire le enumerenbrepiece dans ma requete

en effet ,elle ne me sert a rien car je n'y recherche rien , je voulais juste obtenir la reference ,designation et le prix d'une prestation en fonction du nbre de piece selectionné par l'utilisateur dans son select box.

donc d'apres toi il m'est inutile de l'intorduireapres le from .ma requete peut etre donc plus simplement:

Code : Tout sélectionner

SELECT enumereinituleprestation.NomIntitule,enumereintituleprestation.DesignationIntitule,enumereprixforfait1.PrixTtc FROM enumereintituleprestation,enumereprixforfait1 WHERE enumereprixforfait1.idPiece='".$_POST['NbrePIeceSelectionneParFormulaire']."'
ai je raison ou trot??merci d'avance

Posté : 18 janv. 2008, 15:39
par newby
argh je deviens fou ,je viens d epenser que mon $_post me renvoyait du texte et non un identifiant:
en fait pour mon select box va puisé les noms qu'il propose dans la table enumerenbrepiece.


donc il faut d'abord que je compare le texte renvoyé par mon select box et j'en trouve un identifant idPiece et ensuite je cherche dans ma table enumereprixforfait1 la ligne qui me propose cet identifiant idPiece

Code : Tout sélectionner

SELECT enumereinituleprestation.NomIntitule,enumereintituleprestation.DesignationIntitule,enumereprixforfait1.PrixTtc FROM enumereintituleprestation,enumereprixforfait1 WHERE enumerenbrepiece.TitrePiece='".$_POST['NbrePIeceSelectionneParFormulaire']."' est ce que mysql va comprendre qu'il doit se basé sur cet identifiant?? merci

Posté : 18 janv. 2008, 15:59
par Berzemus
Est-que dans enumereintituleprestation et enumereprixforfait1 il y a une valeur qui permettrait de lier les tables entre eux ? (genre un numéro d'identification ou quelque chôse comme ça)

Posté : 18 janv. 2008, 16:23
par newby
enumereprixforfait1 presente une colonne qui porte le meme nom (idIntitule) que la colonne (idIntitule) de la table enumereintituleprestation.Tout simplement car je peux mettre dans la colonne l'identifiant qui correpond au type de prestatin qui doit etre realisé.

Regarde les insert inot d'exemple tout en haut et demande des expliquations afin que je puisse t'aider à mieux cerner ..

je l'ai fait expres car je vais avoir une vingtaine de formule a proposer en tout .


merci a toi

Posté : 18 janv. 2008, 17:37
par Berzemus
Alors il suffit de mettre un JOIN pour que MySQL puisse s'y retrouver..

Code : Tout sélectionner

SELECT A.NomIntitule as NomIntitule, A.DesignationIntitule as DesignationIntitule,C.PrixTtc as PrixTtc FROM enumereintituleprestation as A INNER JOIN enumereprixforfait1 as C ON( A.idIntitule = C.idIntitule) WHERE C.idPiece='".$_POST['NbrePIeceSelectionneParFormulaire']."' AND A.NomInituleprestation='".$_POST['NbreDePrestationSelectionneParFormulaire']."' ";

Posté : 18 janv. 2008, 23:32
par newby
je viens de parcourir un pue le net et je viens de voir que Natural join serait parfait appremment car j'ai bien des noms de colonne identique entre les deux tables.


Qu'en pense tu ?Et je voulais savoir quand tu parlais de renommer directement les tables avec AS ,est ce que ca modifiera leurs noms au sein de ma abse de donnée ou est ce juste une maniere d'etre plus lisible au sein de ma requete .Eb effet je evux qu'elle garde le meme nom .
merci d'avance.

Posté : 19 janv. 2008, 01:38
par Berzemus
C'est juste au niveau de la requête, le rennomage; moins tu écris, moins tu risques de faire des fautes. Donc quand on peut s'éviter des efforts, faut pas hésiter :wink:

Un simple inner join devrait suffire. Tu as essayé ma requête dans phpmyadmin ? est-ce que les résultats ne conviennent pas ?

Pour ce qui est de tes premières questions (que je viens de relire :wink: ):
1) l'importance des colonnes n'a de l'importance que pour toi; Pour la db et pour le script, c'est du pareil au même.

3) pour lire les résultats, regarde du côté de mysql_fetch_assoc.


Et le 2, ben il est en cours :wink:

Posté : 19 janv. 2008, 02:45
par Hubert Roksor
Concernant ce "renommage", le terme exact est "alias", qui, comme son nom l'indique, consiste à se référer à une chose par autre nom que le sien. Ça évite les quiproquos.

Posté : 19 janv. 2008, 11:59
par Berzemus
Ah oui, alias.. et ça évite les erreurs quand on utilise des noms à rallonge, que je conseillerais d'éviter pour allourdir son script.

Posté : 21 janv. 2008, 13:06
par newby
merci encore pour vos consiels avisé
ma requete finale pares mure reflexion serait donc :

SELECT A.PrixTtc as PrixTtc,B.NomIntitule as NomIntitule,B.DesignationIntitule as DesignationIntitule FROM enumereprixernt as A INNER JOIN enumereintituleprestation as B ON (A.IdIntitule=B.IdIntitule) INNER JOIN enumerenbrepriece as C ON (A.IdPiece=C.IdPiece) WHERE C.TitrePiece=F1

J'ai pris F1 comme resultat de ce que me renverrait mon formulaire .

Mais dans php my admin,je n'arrive pas a tester je clique sur ma base de donnée et choisit requete et je selectionne mes 3 tables dans lm'encadré UTILISER LES TABLES et j'ecrit ma requete dans l'encadre REQUETE SQL DANS LA TABLE et j'ai choisit pour les champs
enumereprixernt,PrixTtc
enumereintutleprestation,NomPrestation
enumereintituleprestation,DesignationPrestation

il reaffiche ma page avec ma requete modifié tel que :
SELECT `enumereprixernt`.`PrixTtc`
FROM enumereprixernt, enumereintituleprestation
et un joli message d'erreur :
Vous devez choisir au moins une colonne à afficher

Ou ai je fauté??
merci

Posté : 21 janv. 2008, 13:50
par Berzemus
"utiliser les tables " ? ahbon.

Simplement sélectionner la DB, et simplement aller dans "SQL" devrait très bien aller; pas besoin de préselectionner des tables..

Posté : 21 janv. 2008, 19:46
par newby
La derniere requete precedente marche tout a fait et revnoit le resultat attendu.

Maintenant ,je voudrais pousser le bouchon un peu plus loin,etant donné que mes noms de colonnes siont identiques entre deux tables liés,j'ai voulu utilisé NORMAL JOIN qui selon la documentation permet d'eviter de preciser les champs qui sont identiques .

Ma requete est du style

SELECT A.PrixTtc as PrixTtc,B.NomIntitule as NomIntitule,B.DesignationIntitule as DesignationIntitule enumereprixamiante as A NORMAL JOIN enumereintituleprestation as B NORMAL JOIN enumerenbrepiece as C WHERE C.TitrePiece="Maison"

cependant celle ci ne marche pas et sql me renvoit l'erreur suivante:
MySQL a répondu:Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'enumereprixamiante as A NORMAL JOIN enumereintituleprestation as B NORMAL JOIN ' at line 1

quelqu'un aurait il une idée svp?
merci