problème d'extraction de données

problème d'extraction de données - PHP - Programmation

Marsh Posté le 11-02-2010 à 16:38:11    

Bonjour à tous,
 
Je bloque depuis deux jours sur une requête pour extraire des données de plusieurs tables (pour le site de restaurant). Je dois en effet extraire les données 'Lib_Prod' et 'Annee_Prod' de la table 'PRODUITS', 'Appellation' de la table 'CARAC_VINS' et 'Prix_TTC_Article' de la table 'ARTICLES'.(voir image de la base ci-dessous)
Ce qui doit me donner quelque chose comme cela:
 
Noms | Année | Appellation | Prix
Domaine Maupas | 2006 | Chablis | 35.00 €
François Villard | 2007 | Côtes du Rhône | 50.00 €
Guérin Vergisson | 2005 | Saint-véran | 30.00 €
 
Voici la partie de ma base qui nous intéresse (en tout cas moi ):
http://i68.photobucket.com/albums/i7/Anatal/requete.gif
 
Jusque là pas de problème, avec la requête suivante j'ai réussi à extraire ce que je voulais:
Code PHP :
 
$listVinsBlancs = "SELECT DISTINCT LIB_PROD, ANNEE_PROD, APPELLATION, PRIX_TTC_ARTICLE
FROM produits
INNER JOIN est_produit  
ON produits.ID_PROD = est_produit.ID_PROD  
INNER JOIN articles  
ON articles.ID_ARTICLE = est_produit.ID_ARTICLE  
INNER JOIN cat_produit  
ON cat_produit.ID_CAT_PROD = produits.ID_CAT_PROD  
INNER JOIN carac_vins
ON produits.ID_CARAC_VIN = carac_vins.ID_CARAC_VIN
INNER JOIN unites
ON articles.ID_UNITE = unites.ID_UNITE
WHERE cat_produit.ID_CAT_PROD = '48' //le code pour le vin blanc
AND produits.EN_VENTE = '1' //égale à 'en stock'
AND articles.ID_MENU = '0' //ne fait pas partie d'un menu
AND unites.ID_UNITE = '6' //6 est égale à 'bouteille'
ORDER BY articles.PRIX_TTC_ARTICLE ASC;";
 
Là où ça se complique c'est que le prix indiqué est égal au prix d'une bouteille, et que je dois aussi indiquer le prix de la 1/2 bouteille et du verre.
 
Ces prix sont dans ma table 'ARTICLES' un produit (ex:'Domaine Maupas') est donc indiqué 3 fois dans ma table 'ARTICLES' pour la bouteille, la demie-bouteille et la verre. La différence se fait par la référence à l'Id_Unite (6 = bouteille, 7 = demie-bouteille, 5 = verre).
 
De plus, pour certains produits on ne vend pas de 1/2 bouteille ni de verre. Donc il se peut qu'il existe 1, 2 ou 3 occurrences dans la table 'ARTICLES' pour le même produit et je ne sais pas comment afficher dans le même tableau toutes données, surtout quand les occurrences sont inexistantes, pour donner un résultats comme celui-ci:
 
Noms | Année | Appellation | Prix bout. | Prix 1/2 bout. | Prix du verre
Domaine Maupas | 2006 | Chablis | 35.00 € | 19.00 € | n.a.
François Villard | 2007 | Côtes du Rhône | 50.00 € | 27.00 € | 9.00€
Guérin Vergisson | 2005 | Saint-véran | 30.00 € | n.a. | n.a.
 
Si vous avez une piste je vous écoute. Et si jamais vous manquez de renseignements pour me répondre demandez moi, à force d'être plongé dedans j'en oublie parfois de donner des détails essentiels à la compréhension du problème.
 
Merci à l'avance de votre attention.


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 11-02-2010 à 16:38:11   

Reply

Marsh Posté le 11-02-2010 à 16:48:27    

a voir ta structure de table, mais une des solutions est de faire 3 left outer join sur ta table article pour chopper les 3 prix différents

Reply

Marsh Posté le 11-02-2010 à 17:00:59    

Pourriez vous être un peu plus précis svp?
J'ai du mal à vous comprendre.


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 11-02-2010 à 17:14:04    

ce que dit casimimir c'est qu'il faudrait faire des "left outer join" au lieu de certains inner join pour renvoyer également les produits n'ayant pas de correspondance dans articles.

Reply

Marsh Posté le 11-02-2010 à 17:16:16    

Ok je ne connais pas trop la différence entre les deux, je regarde ça et je vous tiens au courant, merci.


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 11-02-2010 à 18:11:58    

J'ai un doute quand même...
 
LEFT OUTER JOIN  permet bien de "rapatrier le maximum d'informations disponible, même si des lignes de table ne sont pas renseignées entre les différentes tables jointes" mais cela ne règle pas entièrement le problème. En effet si je lance ma requête en remplaçant INNER JOIN par LEFT OUTER JOIN et en réglant unites.ID_UNITE  à 5 et non 6 (c'est à dire 'verre' au lieu de 'bouteille') j'obtiens bien :
 
Noms | Année | Appellation | Prix du verre
Domaine Maupas | 2006 | Chablis | null
François Villard | 2007 | Côtes du Rhône | 9.00€
Guérin Vergisson | 2005 | Saint-véran | null  
 
Ce qui est déjà beaucoup mieux!
Mais le fond du problème c'est surtout comment afficher les 3 prix dans le même tableau? Parce que là nous ne parlons pas d'une ligne non renseignée mais carrément d'une fiche manquante! Comme je l'expliquais précédemment, le même produit peut apparait 1, 2 ou 3 fois dans la table 'ARTICLES' (donc sous 1, 2 ou 3 'ARTICLES.Id_Article' différents mais un seul 'ARTICLES.Id_Prod').
 
Donc dire faire dans la même requête :
 
"Afficher le NOM (PRODUITS.Lib_Prod), l'année (PRODUITS.Annee_Prod), l'appellation (CARAC_VINS.Appellation), le prix de la bouteille (ARTICLES.Prix_TTC_Article), le prix de la 1/2 bouteille (ARTICLES.Prix_TTC_Article), et le prix du verre (ARTICLES.Prix_TTC_Article)."
 
Comme on le voit ici les 3 prix ont le même nom (ARTICLES.Prix_TTC_Article) puisqu'ils ne sont pas sur la même fiche. C'est la valeur (ARTICLES.Id_Unite) qui les distingue - et (ARTICLES.Id_ARTICLE) qui est la clé primaire de cette table biensûr.
 
Pour illustrer avec le propos, deux exemples, l'un complet et l'autre avec une occurrence en moins:
1°/ Ce que je recherche à l'affichage:
 
Noms | Année | Appellation | Prix bout. | Prix 1/2 bout. | Prix du verre
Domaine Maupas | 2006 | Chablis | 35.00 € | 19.00 € | null  
François Villard | 2007 | Côtes du Rhône | 50.00 € | 27.00 € | 9.00 €  
 
2°/ Les occurrences de la table 'ARTICLES' :
 
Id_Article  |  Id_Unite | Prix_TTC_Article
      1       |      6      |       35.00           (lié à Id_Prod = 1 dans la table 'EST_PRODUIT' donc 'Domaine Maupas')
      2       |      7      |       19.00           (lié à Id_Prod = 1 dans la table 'EST_PRODUIT' donc 'Domaine Maupas')
      3       |      6      |       50.00           (lié à Id_Prod = 2 dans la table 'EST_PRODUIT' donc 'François Villard')  
      4       |      7      |       27.00           (lié à Id_Prod = 2 dans la table 'EST_PRODUIT' donc 'François Villard')
      5       |      5      |       9.00             (lié à Id_Prod = 2 dans la table 'EST_PRODUIT' donc 'François Villard')
 
En résumé pour 'Domaine Maupas' 2 fiches, et pour 'François Villard' 3 fiches, et à chaque fois on doit extraire un valeur qui porte le même nom de champ 'ARTICLES.Prix_TTC_Article'.
 
Bref je patauge...  :(


Message édité par SV_LVH le 11-02-2010 à 18:13:32

---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 12-02-2010 à 04:21:43    

Personne n'a d'idée concernant ce problème?


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 12-02-2010 à 11:30:42    

Je ne suis pas rentré dans les détails de ta requête, mais je pense que tu devrais utiliser les alias de tables, et appelle 3x la table unité (au moins) avec des alias différents
ex:

 

SELECT [...], verre.prix_TTC, bouteille.prix_TTC, demib.prix_TTC
FROM [...],
LEFT JOIN articles as verre ON [...]
LEFT JOIN articles as bouteille ON [...]
LEFT JOIN articles as demib ON [...]
WHERE [...]

 

le LEFT JOIN permet d'avoir des valeurs nulles si t'as pas de résultats.
par contre tu devras peut-être multiplier les alias de tables pour chacune des jointures.
Au final pour l'utiliser dans ton appli, je te recommande de faire une vue avec cette requête, et de l'appeller ensuite dans ton code. ça sera moins casse pied.


Message édité par PunkRod le 12-02-2010 à 11:31:12
Reply

Marsh Posté le 12-02-2010 à 17:23:33    

Après une grande discussion avec un collègue plus compétant que moi en php/sql, la décision a été prise de modifier la base de données. Les problèmes rencontrés viennent d'un défaut de conception de la base qui risque de de créer des complications à répétition pour toutes les autres requêtes du site.
 
C'est navrant de devoir retoucher à la DB à ce stade, mais c'est une décision logique. Donc je ravale mon envie de tout casser et je retourne voir mon ami Sybase  :ange:  
 
Et tout cas merci pour vos réponses.


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed