Requete INNER JOIN - Apprendre-PHP.com

Rechercher
PHP5 Avancé - Eric Daspet et Cyril Pierre de Geyer - Commander sur Amazon.fr

Requete INNER JOIN

Par paintbox -  66 reponses -  Le 08/11/2010 -  Flux RSS - 

Bonjour à tous,

 

J'ai un petit problème de requete sql.

j'ai une table produits et une table couleurs.

La table produit contient évidement tous mes produits avec divers champs. La table couleurs elle est composée de "ID_couelur", "code_couleur" (=code pour la couleur) , "couleur" (=nom de la couleur).

 

Dans ma table produits, j'ai plusieurs champs qui font référence au champs  "code_couleur" de la table "couleurs".

 

lors de ma requete, sql je fais un "INNER JOIN" pour joindre ma table produit avec ma table couleurs.

 

Lors de l'affichage de mes données. je fais un "$donnees_produits['couleur_clip']" et "$donnees_produits['couleur_corps']" (qui sont des champs de la table Produits).  Ces 2 données doivent vérifier le code_couleur correspondant dans la table "couleurs". Hors cela se fait uniquement pour le premier affichage qui fait référence à la table couleurs et pas pour les suivants où il affiche simplement le code couleur tel qu'il apparaît. 

 

Ma question est donc comment faire apparaître le contenu de la colonne couleur correspondant au champs " code_couleur" et cela pour chacun des champs de la table produit qui font appel au champs "code_couleur".

 

Voilà j'espère que c'est clair… j'avoue que ce n'est pas évident à expliquer.

 

Réponses apportées à cette discussion

Par Cyrano -  Le 08/11/2010 - 

Clair, pas complètement : si tu nous montrais ta requête SQL, on gagnerait à mon vis pas mal de temps ;)

 

 
Par paintbox -  Le 08/11/2010 - 

Bonjour Cyrano,

 

je me doutais que ça ne serait pas clair.

 

Voici donc ma requete et l'affichage des données.

 

  1. $selected_stylo=$_GET['id_stylo'];
  2. $previous_page=$_SERVER['HTTP_REFERER'];
  3. echo '<p id="return"><a href='.$previous_page.'>Retour à la page précédente</a></p>';
  4. $sql_fiche=mysql_query("SELECT stylo.id_stylo, stylo.ref_stylo, stylo.longueur,stylo.prix_vente,stylo.couleur_add, stylo.couleur_corps, stylo.code_couleur_encre, stylo.couleur_clip, couleur_poussoir, stylo.code_matiere,stylo.code_print, stylo.nom_produit,
  5. images.chemin_image, images.id_stylo, images.rang,
  6. matiere.code_matiere, matiere.matiere,
  7. print.code_print,
  8. couleur.code_couleur, couleur.couleur
  9. FROM stylo
  10. INNER JOIN images ON images.id_stylo=stylo.id_stylo
  11. INNER JOIN couleur ON couleur.code_couleur=stylo.couleur_corps
  12. INNER JOIN matiere ON matiere.code_matiere=stylo.code_matiere
  13. INNER JOIN print ON print.code_print=stylo.code_print
  14. WHERE stylo.id_stylo='".$selected_stylo."' AND images.rang='2'") or die("Sélection de la base impossible !");
  15. $donnees_fiche =mysql_fetch_assoc($sql_fiche);
  16. echo $selected_stylo;
  17. echo '<div class="bloc_fiche">';
  18. echo '<div class="bloc_gauche"><img src="'.$donnees_fiche['chemin_image'].'" id="bloc_image"</div>';
  19. echo '<div class="bloc_droite">';
  20. echo '<table class="table_fiche">';
  21. echo '<tr>';
  22. echo '<th colspan="2"><h3>'.$donnees_fiche['ref_stylo'].' - '.$donnees_fiche['nom_produit'].'</h3></th>';
  23. echo '</tr>';
  24.  
  25. echo '<tr>';
  26. echo '<td>Longueur : </td>';
  27. echo '<td>± '.$donnees_fiche['longueur'].' cm</td>';
  28. echo '</tr>';
  29. echo '<tr>';
  30. echo '<td>Couleur du corps : </td>';
  31. echo '<td>'.$donnees_fiche['couleur'].'</td>';
  32. echo '</tr>';
  33. echo '<tr>';
  34. echo '<td>Couleur clip : </td>';
  35. echo '<td>'.$donnees_fiche['couleur_clip'].'</td>';
  36. echo '</tr>';
  37. echo '<tr>';
  38. echo '<td>Couleur poussoir : </td>';
  39. echo '<td>'.$donnees_fiche['couleur_poussoir'].'</t>';
  40. echo '</tr>';
  41. echo '<tr>';
  42. echo '<td>Matière : </td>';
  43. echo '<td>'.$donnees_fiche['matiere'].'</td>';
  44. echo '</tr>';
  45. echo '</table>';
  46. echo '</div>';
  47. echo '<div id="gamme">';
  48. echo '<br />';
  49. echo '<p>Dans la même gamme :</p>';
  50. echo '</div>';

 

Couleur,  couleur_clip et couleur_poussoir font appel au champ "code_couleur" mais seulement couleur affiche le bon intitulé de couleur.

 

 
Par Cyrano -  Le 08/11/2010 - 

Ok, alors on va y aller en limitant au SQL dans un premier temps : première règle, mettre au point la requête SQL avant de l'intégrer avec des paramètres dynamiques. En d'autres termes, on va tester la requête avec des paramètres en dur directement dans MySQL : quand le résultat correspondra à ce que tu attends, tu pourras l'intégrer en remplaçant les paramètres par des variables.

D'abord, voyons la requête :

Requête originale
  1. SELECT
  2. s.id_stylo,
  3. s.ref_stylo,
  4. s.longueur,
  5. s.prix_vente,
  6. s.couleur_add,
  7. s.couleur_corps,
  8. s.code_couleur_encre,
  9. s.couleur_clip,
  10. couleur_poussoir,
  11. s.code_matiere,
  12. s.code_print,
  13. s.nom_produit,
  14. i.chemin_image,
  15. i.id_stylo,
  16. i.rang,
  17. m.code_matiere,
  18. m.matiere,
  19. p.code_print,
  20. c.code_couleur,
  21. c.couleur
  22. FROM stylo s
  23. INNER JOIN images i ON i.id_stylo = s.id_stylo
  24. INNER JOIN couleur c ON c.code_couleur = s.couleur_corps
  25. INNER JOIN matiere m ON m.code_matiere = s.code_matiere
  26. INNER JOIN print p ON p.code_print = s.code_print
  27. WHERE s.id_stylo = '". $selected_s ."'
  28. AND i.rang = 2;

Première observation, il y a des redondances dans les données recherchées : id_stylo, code_matiere et code_print sont deux fois dans la derequête depuis leurs tables respectives, mais en sortie, ça ne sert qu'à créer des conflits. Ensuite, tu peux utiliser des alias pour tes noms de tables, ça va éclaircir par mal le code et en faciliter la lectur. Au final, on obtient ceci :

Requête nettoyée :
  1. SELECT
  2. s.id_stylo,
  3. s.ref_stylo,
  4. s.longueur,
  5. s.prix_vente,
  6. s.couleur_add,
  7. s.couleur_corps,
  8. s.code_couleur_encre,
  9. s.couleur_clip,
  10. couleur_poussoir,
  11. s.nom_produit,
  12. i.chemin_image,
  13. i.rang,
  14. m.code_matiere,
  15. m.matiere,
  16. p.code_print,
  17. c.code_couleur,
  18. c.couleur
  19. FROM stylo s
  20. INNER JOIN images i ON i.id_stylo = s.id_stylo
  21. INNER JOIN couleur c ON c.code_couleur = s.couleur_corps
  22. INNER JOIN matiere m ON m.code_matiere = s.code_matiere
  23. INNER JOIN print p ON p.code_print = s.code_print
  24. WHERE s.id_stylo = '". $selected_s ."'
  25. AND i.rang = 2;

Maintenant, remplace ta variale $selected_s par une valeur existante dans ta base et colle ça dans phpMyAdmin pour observer le résultat : Pose-toi alors la question suivante : est-ce que dans les données retournées il y a tous les éléments dont tu as besoin pour l'affichage à construire dans ta page ?

Et reviens ensuite avec ça :)

 

 

 

 
Par paintbox -  Le 08/11/2010 - 

J'ignorais qu'on pouvait "appeler" une table juste à l'aide de sa première lettre. Pour autant qu'on l'ai définit comme suit je suppose : "INNER JOIN images i ON i.id_stylo = s.id_stylo".

Et donc   id_stylo, code_matiere et code_print qui interviennent dans plusieurs tables, ne doivent définit qu'une seule fois dans la requete?

 

J'ai donc coller ma requete dans phpMyadmin (ce que je fais normalement d'ahibitude pour tester) et oui j'obtiens le bon résultat sauf que au lieu d'avoir l'intitulé de la couleur j'ai son code comme il est définit dans les champs respectifs de ma table stylo.

Comme à chaque fois, j'apprend de nouvelles choses, merci ! 

 

 
Par Cyrano -  Le 08/11/2010 - 

C'est ce qu'on appelle un « alias » : j'ai utilisé la première lettre de chaque table, mais ce n,est nullement une obligation. Tu définis toi-même ton alias qui peut être limité à une lettre mais aussi en comporter davantage.

Quant à tes données retournées, tu dis « au lieu d'avoir l'intitulé de la couleur j'ai son code » Est-ce que la donnée est bonne dans la table ? Si oui, alors peut-être ne demandes-tu pas la bonne.

Lorsque tu construis une requête SQL de type SELECT, tu dois distinguer plusieurs choses :

 

  1. Les colonnes dont tu as besoin, en général en un seul exemplaire mais il peut arriver dans certains cas qu'on ait besoin de plusieurs occurrences d'une même colonne avec pour chacune des conditions différentes;
  2. Les tables dans lesquelles trouver ces données et les conditions de jointures;
  3. Les clauses de tri (WHERE)
  4. éventuellement d'autres clauses particulières (HAVING, ORDER BY, GROUP BY, LIMIT, etc..)

C'est qui est important de comprendre, c'est que pour le point 1, tu n'as aucune obligation de mentionner une colonne si tu n'as pas besoin de sa valeur en retour, même si cette colonne est utilisée dans les clauses de jointure ou de tri. Donc il est possible que tu puisse effectivement retirer encore quelques colonnes inutiles dans la liste qui précède le FROM.

 

 

 
Par paintbox -  Le 08/11/2010 - 

En fait je crois que ce sera plus simple d'expliquer comme ceci.

J'ai donc une table "COULEUR"  qui comprend les champs suivants :

• id_couleur (en autoincrément)

• code_couleur qui se présente comme ceci (1000, 1100, 1200, 1300, 1400…)

• couleur qui a pour valeur (Blanc, Jaune, Rouge, Vert…)

 et donc le code_couleur 1000 correspond à la couleur Blanc.

 

J'ai également  ma table "STYLO" qui contient tous les stylos et dont certain champ décrit la couleur des certaines parties d'un stylo ex: couleur_corps, couleur_clip, couleur_poussoir… pour ces champs, je donne le code_couleur correspondant (donc, 1000, 1400…).

 

Donc dans ma requete je fais appel aux champs  couleur_corps, couleur_clip, couleur_poussoir et pour trouver "l'intitulé" du code couleur correspondant, je fais un INNER JOIN avec la table "COULEUR".

Mais donc mon problème c'est que je ne sais faire qu'une seule fois la jointure avec la table COULEUR.

Est-ce plus clair comme ceci? 

 

 

 
Par Cyrano -  Le 08/11/2010 - 

Plus ou moins, je me demande si ton modèle de données reflète réellement l'organisation de ton système de classement. Si ce n'est pas le cas, transformer ça en code risque d'être un peu laborieux.

Pour l'instant, ce que je comprends, c'est qu'un stylo est composé de différentes pièces et qu'à chaque pièce correspond une couleur. Je me demande si on peut raisonnablement représenter ça avec uniquement deux tables... Il me manque peut-être des éléments pour pousser la réflexion sur la question. 

 

 
Par paintbox -  Le 08/11/2010 - 

j'ai cru simplifier en créant une table couleur, ce qui m'évitait à chaque fois d'encoder en toute lettre la couleur, mais je crois que j'ai plutôt compliqué les choses. L'idée était en créant cette table couleur de pouvoir la réutiliser pour d'autre tables CRAYON, MARQUEUR…

 

Tu crois que je ferais mieux d'indiquer en toute lettre la couleur dans le champs? 

 
Par Cyrano -  Le 09/11/2010 - 

non du tout, ce n'est pas ce que je voulais dire et au contraire, traiter les codes couleur dans une table à part te laisse beaucoup plus de liberté d'action. Non, le problème serait au contraire au niveau du stylo : en réalité un stylo est une composition de pièces et je me demande si on peut résumer le stylo en une seule table.

Pour le déterminer, il faut décomposer les informations et se demander si chacun ne peut avoir de lien qu'avec 0, 1 ou n autre type d'information, et ce dans les deux sens. C'est la recherche de ce qu'on appelle les cardinalités.

Là, nous pourrions par exemple couper ça en deux, une entité stylo et une entité pièce : ainsi, le stylo a 0 ou 1 exemplaire de telle pièce et à cette pièce  correspond tel code couleur. Ce serait plus logique si on considère par exemple qu'un même stylo peut avoir un capuchon bleu ou un capuchon vert.

Est-ce que tu perçois mieux ce que je veux dire ? 

 
Par paintbox -  Le 09/11/2010 - 

Bonjour Cyrano,

 

donc si je comprends bien, j'aurai une table stylo avec :

 

• id_stylo

• ref_stylo

• nom_stylo

• largeur

• longueur

Une table pièces_stylo avec :

• couleur_corps

• couleur_clip

• couleur_poussoir

 

j'ai en fait le même problème avec une table matière (métal, ABS…)  je peux rajouter les champs dans la même table?

• matière_corps

• matière_clip

• matière_poussoir

 

 

Est-ce correcte?

 
Par Cyrano -  Le 09/11/2010 - 

Pas tout à fait : observe bien les deux dernières tables que tu suggères : il y a redondance au niveau des pièces. En plus tu introduis un nouvel élément : la matière.

Donc résumons :

  • un stylo est composé de 1 à n pièces;
  • Une pièce peut est partie de 0 à n stylos;
  • Une pièce a une (et une seule ?) couleur;
  • une pièce est faite d'une (et une seule ?) matière;
  • Une couleur peut concerner 0 à n pièces;
  • Une matière peut constituer 0 à n pièces

Je distingue là 4 entités : stylo, pièce, matière et couleur. Chacune de ces entités a des propriétés qui lui sont propres : un identifiant, un libellé, autres...

Juste une question, quel outil utilises-tu pour modéliser tes bases ?

 

 
Par paintbox -  Le 09/11/2010 - 

Je n'utilise pas de logiciel pour modéliser  mes bases. Je suis sur Mac et j'avais tester MSQLWorkbench il y a quelques temps mais je n'étais pas convaincu. Je le fais finalement sur papier. 

Oui ton analyse me semble juste. Je devrais donc créer les tables stylo, pièce, matière et couleur + des tables intermédiaires qui reprendraient par ex les champs id_stylo et id_pièce qui permet de lier la table stylo à la table pièce?

 

Je vais avoir également un autre soucis. Pour chaque stylo, j'ai différents prix pour différentes quantités. Dois-je créer une table quantité et une autre prix?

 
Par Cyrano -  Le 09/11/2010 - 

Les variantes dans les prix concernent un autre élément : les commandes, donc ce n'est pas à mettre directement dans une des entités de base. Et même là, une commande va comporter un certain nombre de lignes correspondant aux articles avec des quantités et tu peux avoir une entité pour les remises avec des critères de quantité en fonction d'un article ou un autre.

Pour MySQL WorkBench, c'est personnellement ce que j'utilise faute d'avoir les moyens de m'offrir PowerAMC qui à ma connaissance n'a pas de concurrent sérieux pour faire de la vraie modélisation en méthode MERISE.

 

Enfin, les tables relationnelles ne doivent exister que selon certaines conditions : connais-tu le principe des cardinalités entre les entités ? Oublie pour l'instant les notions te tables et de colonnes. Principe de base :

  1. +----------+ +----------+
  2. | Entité-1 | | Entité-2 |
  3. +----------+ __________ +----------+
  4. | prop_1 | 0:1 / concerne \ 1:1 | prop_1 |
  5. | prop_2 |----------------------------| prop_2 |
  6. | ... | \__________/ | ... |
  7. | prop_n | | prop_n |
  8. +----------+ +----------+

Ici par exemple, nous avons Entité-1 qui correspond à 0 ou 1 occurence de Entité-2, et dans l'autre sens, une occurence de Entité-2 ne peut correspondre qu'à une et une seule occurence de Entité-1.

Les correspondances peuvent être 0:1, 0:n, 1:1 et 1:n :on met du coté de l'entité le nombre de correspondances dans l'autre entité.

À ce stade du graphique, on ne met pas de clés étrangère, c'est le modèle conceptuel de données (MCD) : les notions de clés étrangères n'interviendront que lors de la phase suivante, le modèle physique de données (MDP) Ça,ce sont les bases fondamentales. Dans la listes des données que tu dois manipuler, tu dois définir les liens entre elles : si tu as par exemple 1:1 de chaque coté d'une relation, il est probable que tu as affaire à une entiuté d'un coté et à une propriété de cette même entité de l,autre : en fin de compte, ce ne sont donc pas deux entités distincte. Mais si sur un des cotés tu as un 0:n ou 1:n, alors tu as affaire à une entité et non une propriété. Dans le modèle physique apparaîtront des clés étrangères et des tables relationnelles qui n'ont pasà être indiquées dans le MCD autrementque par les cardinalités. MySQL-WorkBench fait en quelque sorte directement du MPD en l'affichant au fur et à mesure que tu places tes relations. Ce n'est pas mauvais en soi mais ça rend l'apprentissage plus flou si tu n'as pas ces connaissances de base.

Et au passage, considère que passer du temps sur cette phase n'est vraiment pas une perte de temps : une modélisation bancale ne pourra donner lieu qu'à une application bancale, si bien codée soit-elle ;)

 
Par paintbox -  Le 09/11/2010 - 

OUi je me suis déjà documenté sur les cardinalités.

 

Donc si je comprend bien, j'ai ceci

 

• stylo -- 1.N --Compose --0.N -- Pièces

• Pièces -- 1.1 -- Est composé de -- N.1 Matières

• Pièces -- 1.N -- est -- 0.N -- Couleurs

 

Est-ce correcte ?

 
Par Cyrano -  Le 09/11/2010 - 

Pas totalement logique ton montage,observe bien :

Un stylo est composé de combien de pièces ? Au moins une, au maximum n, « n » voulant dire un nombre indéterminé supérieur ou égal à 1 : donc c'est correct coté stylo; dans l'autre sens, une pièce peut être utilisée pour la construction de 0 à n stylos, entends par là qu'une pièce peut ne pas être utilisée du tout ou bien être un composant pour différents modèles de stylos. Pour la relation style//pièce, c'est correct.

Une pièce est  constituée de une et une seule matière, là aussi, on est bon. Par contre,« N: »1 n'existe pas, revois la liste que j'ai mentionné plus tôt. Si on inverse, on obtient qu'une matière peut servir à créer 1 à n pièces, en réalité, ce devrait être de 0 à n pièces si on considère qu'une matière peut ne pas être utilisée du tout... pendant un certain temps. Note à ce propos que lorsque tu introduiras une nouvelle matière dans ton inventaire, en mettant 1:n, tu seras obligé de lui attacher au moins une pîèce si on veut respecter scrupuleusement la logique, or tu n'auras pas encore construit quoi que ce soit avec cette matière au moment de son ajout, donc 0:n;

Une pièce peut-elle être multicolore ? Sûrement pas. Tu auras peut-être un code couleur correspondant à un décor comprenant un fond d'une couleur avec un motif d'une autre couleur, mais c'est un seul code : donc une pièce aura une et une seule couleur, et ne peut pas ne pas en avoir, donc coté pièce, ce sera 1:1. Coté couleur en revanche, c'est correct puisqu'une couleur peut ou non être utilisée, et si elle l'est, ce sera pour un nombre indéterminé de pièces : donc, 0:n est correct.

Ça, c'est le modèle conceptuel : reprends ce que j'ai expliqué plus tôt et définis maintenant à quoi va ressembler le modèle physique ;)

 

 
Par paintbox -  Le 09/11/2010 - 

Voici ce que j'obtiens mais sui par certain.

 

Donc en me basant sur:

 

• stylo -- Pièces : 1 : N

• Pièces --  Matières : 0 : N

• Pièces -- Couleurs : O : N

 

J'aurais les tables suivantes  ?

 

STYLO

• id_stylo (PK)

• ref_stylo

• ref_fournisseur

• longueur

• epaisseur

• code_print

• delais_prod

 

PIECES

• id_pieces(PK)

• code_piece

• nom_piece

 

STYLO /-PIECE (pour lier piece a stylo)

• id (PK)

• ref_stylo

• code_piece

 

COULEUR

• id_couleur (PK)

• code_couleur

• couleur

 

STYLO - PIECES - COULEUR (lie stylo, piece et couleur)

• id

• code_piece

• code_couleur

 

MATIERES

• id_matiere

• code_matiere

• matiere

STYLO - PIECES - MATIERES (lie stylo, piece et matiere)

• id

• ref_stylo

• code_piece

• code_matiere

 

Est-ce correcte ? 

 
Par Cyrano -  Le 09/11/2010 - 

Tu y es quasiment. Une image vaut mille mots disait Napoléon, jette un coup d'oeil là-dessus. Ce sera plus explicite ;)

À partir de là, tu travailleras beaucoup plus facilement et ta vision globale de la répartition des données devrait être infiniment plus simple :)

Profites-en pour noter au passage une manière de nommer les éléments. C'est une convention de nommage que j'utilise moi-même et que je t'encourage vivement à adopter, ça aussi ça simplifie la vie au moment de coder.

Les tables de base commencent par un « t_ » et se terminent par un suffixe en trigramme : observe que ce trigramme sert de préfixe aux noms de colonnes de la table. Les clés étrangères conservent le trigramme de leur table d'origine, c'est plus facile ensuite de se repérer. Quant à la table relationnelle, tu peux aussi noter que la clé primaire est une clé composite faite des deux clés étrangères : pas besoin d'ajouter une clé supplémentaire.

Est-ce que tu t'y retrouves de cette manière ?

 
Par paintbox -  Le 09/11/2010 - 

Oui ça me semble bcp plus clair.

Encore 2 questions.

• Tu as 2 clés primaire dans ta table "stylo_has_piece_shp" Comment fais tu?

• Que me conseils-tu pour mes prix sachant que pour chaque stylo j'ai les prix pour 5000, 10000, 20000 et 30000pcs . Sachant que si j'ai par après les prix pour 40000, 50000… je les ajouterai.

Si j'ai

T_quantite_qua

• qua_id 

• qua_code

• qua_libelle 

et une table liant quantité à stylo

stylo_has_quantite_prix

• id

• sty_id

• qua_id

• prix

 

Est-ce correcte? 

 

 
Par paintbox -  Le 09/11/2010 - 

Je cale du coup sur ma requete

 Comment faire mes liaisons entre mes différentes tables de façon à afficher pour un stylo les différentes pièces, leur couleur…

pour l'instant ma requete donne ceci, mais je bloque

  1. SELECT s.sty_id, s.sty_ref,s.sty_prix_vente,s.sty_couleur_add, s.sty_code_matiere,m.ima_chemin, m.sty_id, im.ima_rang,m.mat_code, m.mat_libelle
  2. FROM t_stylo s
  3. INNER JOIN t_images_ima ON m.sty_id =s.sty_id
  4. INNER JOIN stylo_has_piece_shp ON s.sty_id =sty_id
  5. INNER JOIN t_matiere_mat ON m.code_matiere=stylo.code_matiere
  6. WHERE images.rang='1'

 

 

 
Par Cyrano -  Le 09/11/2010 - 

pour la double clé primaire, ce n'est en fait pas le cas : je te l'ai mentionné, c'est une clé composite consitutuée des deux colonnes, or ces deux colonnes sont les clés étrangères des tables liées. Donc lorsque tu crées une table comme ceci, tu mets les noms des deux colonnes en PRIMARY KEY.

Le code  de création de ce que tu as vu va donner ceci :

  1. SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
  2. SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
  3. SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
  4.  
  5. CREATE SCHEMA IF NOT EXISTS `catalogue` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin ;
  6. SHOW WARNINGS;
  7. USE `catalogue`;
  8.  
  9. -- -----------------------------------------------------
  10. -- Table `catalogue`.`t_stylo_sty`
  11. -- -----------------------------------------------------
  12. DROP TABLE IF EXISTS `catalogue`.`t_stylo_sty` ;
  13.  
  14. SHOW WARNINGS;
  15. CREATE TABLE IF NOT EXISTS `catalogue`.`t_stylo_sty` (
  16. `sty_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  17. `sty_reference` VARCHAR(64) NOT NULL ,
  18. `sty_ref_fournisseur` VARCHAR(64) NOT NULL ,
  19. `sty_longueur` DECIMAL(5,2) NULL ,
  20. `sty_epaisseur` DECIMAL(4,2) NULL ,
  21. `sty_delais_prod` TINYINT NULL ,
  22. PRIMARY KEY (`sty_id`) )
  23. ENGINE = InnoDB
  24. DEFAULT CHARACTER SET = utf8
  25. COLLATE = utf8_bin;
  26.  
  27. SHOW WARNINGS;
  28.  
  29. -- -----------------------------------------------------
  30. -- Table `catalogue`.`t_couleur_cou`
  31. -- -----------------------------------------------------
  32. DROP TABLE IF EXISTS `catalogue`.`t_couleur_cou` ;
  33.  
  34. SHOW WARNINGS;
  35. CREATE TABLE IF NOT EXISTS `catalogue`.`t_couleur_cou` (
  36. `cou_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  37. `cou_code` VARCHAR(64) NOT NULL ,
  38. `cou_libelle` VARCHAR(255) NOT NULL ,
  39. PRIMARY KEY (`cou_id`) )
  40. ENGINE = InnoDB
  41. DEFAULT CHARACTER SET = utf8
  42. COLLATE = utf8_bin;
  43.  
  44. SHOW WARNINGS;
  45.  
  46. -- -----------------------------------------------------
  47. -- Table `catalogue`.`t_matiere_mat`
  48. -- -----------------------------------------------------
  49. DROP TABLE IF EXISTS `catalogue`.`t_matiere_mat` ;
  50.  
  51. SHOW WARNINGS;
  52. CREATE TABLE IF NOT EXISTS `catalogue`.`t_matiere_mat` (
  53. `mat_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  54. `mat_code` VARCHAR(64) NOT NULL ,
  55. `mat_libelle` VARCHAR(255) NOT NULL ,
  56. PRIMARY KEY (`mat_id`) )
  57. ENGINE = InnoDB
  58. DEFAULT CHARACTER SET = utf8
  59. COLLATE = utf8_bin;
  60.  
  61. SHOW WARNINGS;
  62.  
  63. -- -----------------------------------------------------
  64. -- Table `catalogue`.`t_piece_pie`
  65. -- -----------------------------------------------------
  66. DROP TABLE IF EXISTS `catalogue`.`t_piece_pie` ;
  67.  
  68. SHOW WARNINGS;
  69. CREATE TABLE IF NOT EXISTS `catalogue`.`t_piece_pie` (
  70. `pie_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  71. `cou_id` INT UNSIGNED NOT NULL ,
  72. `mat_id` INT UNSIGNED NOT NULL ,
  73. `pie_code` VARCHAR(64) NOT NULL ,
  74. `pie_nom` VARCHAR(64) NOT NULL ,
  75. PRIMARY KEY (`pie_id`) ,
  76. CONSTRAINT `fk_t_couleur_cou1`
  77. FOREIGN KEY (`cou_id` )
  78. REFERENCES `catalogue`.`t_couleur_cou` (`cou_id` )
  79. ON DELETE RESTRICT
  80. ON UPDATE RESTRICT,
  81. CONSTRAINT `fk_t_matiere_mat1`
  82. FOREIGN KEY (`mat_id` )
  83. REFERENCES `catalogue`.`t_matiere_mat` (`mat_id` )
  84. ON DELETE RESTRICT
  85. ON UPDATE RESTRICT)
  86. ENGINE = InnoDB
  87. DEFAULT CHARACTER SET = utf8
  88. COLLATE = utf8_bin;
  89.  
  90. SHOW WARNINGS;
  91. CREATE INDEX `fk_t_couleur_cou1` ON `catalogue`.`t_piece_pie` (`cou_id` ASC) ;
  92.  
  93. SHOW WARNINGS;
  94. CREATE INDEX `fk_t_matiere_mat1` ON `catalogue`.`t_piece_pie` (`mat_id` ASC) ;
  95.  
  96. SHOW WARNINGS;
  97.  
  98. -- -----------------------------------------------------
  99. -- Table `catalogue`.`r_stylo_has_piece_shp`
  100. -- -----------------------------------------------------
  101. DROP TABLE IF EXISTS `catalogue`.`r_stylo_has_piece_shp` ;
  102.  
  103. SHOW WARNINGS;
  104. CREATE TABLE IF NOT EXISTS `catalogue`.`r_stylo_has_piece_shp` (
  105. `sty_id` INT UNSIGNED NOT NULL ,
  106. `pie_id` INT UNSIGNED NOT NULL ,
  107. PRIMARY KEY (`sty_id`, `pie_id`) ,
  108. CONSTRAINT `fk_t_stylo_sty`
  109. FOREIGN KEY (`sty_id` )
  110. REFERENCES `catalogue`.`t_stylo_sty` (`sty_id` )
  111. ON DELETE RESTRICT
  112. ON UPDATE RESTRICT,
  113. CONSTRAINT `fk_t_piece_pie1`
  114. FOREIGN KEY (`pie_id` )
  115. REFERENCES `catalogue`.`t_piece_pie` (`pie_id` )
  116. ON DELETE RESTRICT
  117. ON UPDATE RESTRICT)
  118. ENGINE = InnoDB
  119. DEFAULT CHARACTER SET = utf8
  120. COLLATE = utf8_bin;
  121.  
  122. SHOW WARNINGS;
  123. CREATE INDEX `fk_t_stylo_sty` ON `catalogue`.`r_stylo_has_piece_shp` (`sty_id` ASC) ;
  124.  
  125. SHOW WARNINGS;
  126. CREATE INDEX `fk_t_piece_pie1` ON `catalogue`.`r_stylo_has_piece_shp` (`pie_id` ASC) ;
  127.  
  128. SHOW WARNINGS;
  129.  
  130.  
  131. SET SQL_MODE=@OLD_SQL_MODE;
  132. SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
  133. SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

Maintenant pour tes remises, il faut absoluemtn éviter de stocker des valeurs calculées dans une base de données. Donc, quels sont les critères qui font une remise ? Un pourcentage, une valeur fixe ? On sait que c'est en fonction d'une quantité et que ça concerne un article individuel, donc un stylo. Je serais donc tenté de simplifier(J'ai mis à jour l'image du modèle)

En fin de compte, chaque stylo à son prix en fonction d'une quantité. J'ai donc plusieurs prix possibles pour un stylo, mais un prix ne correspond qu'à un seul stylo. Dans la pratique, il pourrait y avoir un prix similaire entre deux stylos différents, mais c'est une complication de plus à gérer à mon avis. Là, quelque soient les variantes, tu peux en enregistrer autant que nécessaire : un prix pour 1, un pour 1000, un pour 5000, un pour 20000 etc..  Et là, la requête ne sera pas difficile pour obtenir le montant total puisque le critère de tri sera une clause HAVING MAX(prx_quantite) <= nombre-vendus.» ou quelque chose dans ce genre.

 

 

 
Par Cyrano -  Le 09/11/2010 - 

Pour ta requête, crée une vue, ce sera plus simple à l'usage par la suite : le code ressemble à ceci :

Vue v_stylos
  1. CREATE VIEW `catalogue`.`v_stylos` AS
  2. SELECT s.sty_id, s.sty_reference, s.sty_fournisseur, s.sty_longueur, s.sty_epaisseur, s.sty_delais_prod,
  3. p.pie_id, p.pie_code, p.pie_nom,
  4. c.cou_id, c.cou_code, c.cou_libelle,
  5. m.mat_id, m.mat_code, m.mat_libelle,
  6. x.prx_id, x.prx_prix_unitaire, x.prx_quantite
  7. FROM t_stylo_sty s
  8. NATURAL JOIN r_stylo_has_piece_shp r
  9. INNER JOIN t_couleur_cou c ON r.cou_id = c.cou_id
  10. INNER JOIN t_matiere_mat m ON r.mat_id = m.mat_id
  11. INNER JOIN t_prixstylos_prx x ON s.sty_id = x.sty_id
  12. ORDER BY s.sty_id;

Partant de là, tu fais une requête sur v_stylos (préfixe v_ pour une VUE : tu obtiendras très probablement plusieurs lignes pour un même stylo en fonction du nombre de pièces, donc il sera important de faire un ORDER BY sty_id pour ne pas mélanger et ensuite le traitement dans une boucle te permettra de lister toutes lespìeces de chaque stylo.

Je te laisse digérer ça, à mon avis tu as de quoi digérer pour un petit moment ;)

 

 
Par paintbox -  Le 09/11/2010 - 

Je regarde tout cela à mon aise et te tiens au courant. Merci pour ton aide

 
Par paintbox -  Le 10/11/2010 - 

Bonjour Cyrano,

 

je suis en train d'essayer de me familiariser avec MysqlWorkbench. Je n'avais pas compris au début l'utilité et surtout le fait de pouvoir exporter le projet réalisé vers PhpMyadmin.

J'avoue que jusqu'à présent, je créais directement mes bases soit dans PhpMyadmin soit dans SequelPro.

 

j'ai étoffé ma base avec quelques autres  tables dont j'ai besoin. J'espere que c'est bon.

 

J'ai malgré tout quelques questions à propos de Workbench:

• une fois les tables et les relations entre elles faites, peut-ont corriger, modifier et ajouter des éléments? J'ai essayé de modifier une table avec des relations déjà établies, mais je n'y arrive pas.

 

• Si je comprend bien, les vues doivent être créées dans Workbench?

 
 
 
Par Cyrano -  Le 10/11/2010 - 

C'est bien mieux que ça : tu peux synchroniser ton modèle de données MWB avec la base sur ton serveur MySQLen quelques clics.

Qu'est-ce que tu as essayé de modifier et comment  dans ce qui n'a pas fonctionné ?

Tu peux créer les vues au choix dans MWB ou directement dans ta base et procéder à une synchro dans un sens ou dans l'autre ensuite. Lors de la synchro, il te faudra d'abord sélectionner le bon schéma (nom de ta base) et ensuite sélectionner le sens de la synchro : par défaut, c'est du modèle vers la base, mais un double-clic sur une des flèces vertes pointant vers la droite, et ça annule la synchro pour la table concernée, un autre double clic et tu inverses la synchro de la base vers ton modèle.

Et enfin, je crois que tu as découvert toi-même l'export vers un script de création SQL. Tu peux aussi faire un export de ton modèle en png comme je l'ai fait pour pouvoir te le montrer.

L'intérêt général de tout ça, c'est d'abord de t'impregner de  ton modèle de données de façon visuelle et surtout éventuellement de valider tes divers choix.

 

 
Par paintbox -  Le 10/11/2010 - 

J'essaye de créer ma table dans PHPMyadmin mais j'ai le message d'erreur suivant et je ne vois pas trop où est le probleme:

 

requête SQL:

CREATE INDEX `fk_t_categorie_cat_t_stylo_sty1` ON `stylos_promo_2`.`t_categorie_cat` (

`t_stylo_sty_sty_id` ASC

);

 

MySQL a répondu:

 

#1072 - Key column 't_stylo_sty_sty_id' doesn't exist in table  

 
Par Cyrano -  Le 10/11/2010 - 

Peut-être un problème avec le nom de ta colonne ? La syntaxe est :

  1. CREATE INDEX `nom-de-ton-index` ON `nom-du-schema`.`nom-de-la-table` (`nom-de-la-colonne` ASC);

Et là j'ai des doutes sur lenom d'une colonne qui serait « t_stylo_sty_sty_id » ôO

 

 
Par Cyrano -  Le 10/11/2010 - 

J'ajoute quand même que cette colonne a tout d'une clé primaire à première vue : il est donc totalement inutile d'ajouter un index dessus, la clé primaire est déjà un index en soi.

 

 
Par paintbox -  Le 10/11/2010 - 

Nouveau soucis,

 

j'avais créé une table pour les prix des impressions qui dépend également de la quantité.

 

la table se compose comme ceci:

t_print_prt

• prt_id

• prt_code

• prt_prix 

• prt_libelle

 j'avais fais une relation 1:n même si normalement 1 stylo peut avoir n prix et un prix peut etre attribué à n stylo. 

PhpMyadmin me retourne

requête SQL:

CREATE INDEX `fk_t_print_prt_t_stylo_sty1` ON `stylos_promo_2`.`t_print_prt` (

`sty_id` ASC

);

 

MySQL a répondu:

 

#1061 - Duplicate key name 'fk_t_print_prt_t_stylo_sty1'  

 

Est ce que je n'aurais pas plus simple d'ajouter à la table t_prixstylo_prx (déjà existante) une nouvelle colonne avec le prix pour l'impression puisque de toute façon les 2 prix dépendent de la quantité?

 

 
Par Cyrano -  Le 10/11/2010 - 

Essaye de factoriser : il semble que tu aies deux éléments dont il est nécessaire de conserver les prix, mais un prix, c'est une forme d'élément en soi, là même table pourrait peut-être servir pour les deux ?

Je ne sais pas comment tu t'y prends pour ajouter des tables : en ajoutant à la main ou bien en mettant à jour ton modèle puis en synchronisant à partir de MWB ? Parce que dans ce dernier cas, tu n'aurais pas ce genre de problème de doublons d'index, MWB gère lui-même les noms des index.

 

 
Par paintbox -  Le 10/11/2010 - 

Il semblerait que je duplique à nouveau une clé.

Je crois que j'ai encore pas mal de choses à apprendre avec MWB 

Aurais-tu une idée?

Voici mon code

  1. SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
  2. SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
  3. SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
  4.  
  5. CREATE SCHEMA IF NOT EXISTS `stylos_promo_2` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
  6. USE `stylos_promo_2`;
  7.  
  8. -- -----------------------------------------------------
  9. -- Table `stylos_promo_2`.`t_categorie_cat`
  10. -- -----------------------------------------------------
  11. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_categorie_cat` (
  12. `cat_id` INT(5) NOT NULL AUTO_INCREMENT ,
  13. `cat_code_categorie` INT(10) NOT NULL ,
  14. `cat_libelle` VARCHAR(75) CHARACTER SET 'latin1' NOT NULL ,
  15. PRIMARY KEY (`cat_id`) )
  16. ENGINE = INNODB
  17. AUTO_INCREMENT = 4
  18. DEFAULT CHARACTER SET = utf8;
  19.  
  20.  
  21. -- -----------------------------------------------------
  22. -- Table `stylos_promo_2`.`t_couleur_cou`
  23. -- -----------------------------------------------------
  24. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_couleur_cou` (
  25. `cou_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  26. `cou_code` VARCHAR(64) NOT NULL ,
  27. `cou_libelle` VARCHAR(255) NOT NULL ,
  28. PRIMARY KEY (`cou_id`) )
  29. ENGINE = INNODB
  30. AUTO_INCREMENT = 31
  31. DEFAULT CHARACTER SET = utf8;
  32.  
  33.  
  34. -- -----------------------------------------------------
  35. -- Table `stylos_promo_2`.`t_stylo_sty`
  36. -- -----------------------------------------------------
  37. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_stylo_sty` (
  38. `sty_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  39. `sty_reference` VARCHAR(64) NOT NULL ,
  40. `sty_ref_fournisseur` VARCHAR(64) NOT NULL ,
  41. `sty_nom` VARCHAR(50) CHARACTER SET 'latin1' NOT NULL ,
  42. `sty_longueur` DECIMAL(10,2) NULL DEFAULT NULL ,
  43. `sty_epaisseur` DECIMAL(10,2) NULL DEFAULT NULL ,
  44. `couleur_add` VARCHAR(150) CHARACTER SET 'latin1' NOT NULL DEFAULT 'Bleu, Rouge, Vert' ,
  45. `code_couleur_encre` INT(10) NOT NULL DEFAULT '70000' ,
  46. `couleur_corps` INT(10) NOT NULL ,
  47. `couleur_clip` INT(10) NOT NULL ,
  48. `couleur_poussoir` INT(10) NOT NULL ,
  49. `sty_code_matiere` INT(10) NOT NULL ,
  50. `sty_prix_achat` DECIMAL(10,4) NOT NULL ,
  51. `sty_prix_vente` DECIMAL(10,4) NOT NULL ,
  52. `sty_code_print` INT(3) NOT NULL DEFAULT '0' ,
  53. `marge` DECIMAL(10,4) NOT NULL ,
  54. `sty_delais_prod` TINYINT(4) NULL DEFAULT NULL ,
  55. `sty_code_packaging` INT(10) NOT NULL ,
  56. `sty_texte` VARCHAR(500) CHARACTER SET 'latin1' NOT NULL ,
  57. `sty_comment` VARCHAR(500) CHARACTER SET 'latin1' NOT NULL ,
  58. `sty_conditionement` VARCHAR(100) CHARACTER SET 'latin1' NOT NULL DEFAULT 'Cellophane individuel - 50pcs/boîte - 1000pcs/carton' ,
  59. `sty_populair` INT(11) NOT NULL ,
  60. PRIMARY KEY (`sty_id`) )
  61. ENGINE = INNODB
  62. AUTO_INCREMENT = 53
  63. DEFAULT CHARACTER SET = utf8;
  64.  
  65.  
  66. -- -----------------------------------------------------
  67. -- Table `stylos_promo_2`.`t_images_ima`
  68. -- -----------------------------------------------------
  69. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_images_ima` (
  70. `ima_id` INT(10) NOT NULL AUTO_INCREMENT ,
  71. `sty_brol` INT(10) NOT NULL ,
  72. `ima_chemin` VARCHAR(100) CHARACTER SET 'latin1' NOT NULL ,
  73. `ima_rang` VARCHAR(5) CHARACTER SET 'latin1' NOT NULL ,
  74. `sty_id` INT(10) UNSIGNED NOT NULL ,
  75. PRIMARY KEY (`ima_id`) ,
  76. CONSTRAINT `fk_t_images_ima_t_stylo_sty1`
  77. FOREIGN KEY (`sty_id` )
  78. REFERENCES `stylos_promo_2`.`t_stylo_sty` (`sty_id` )
  79. ON DELETE NO ACTION
  80. ON UPDATE NO ACTION)
  81. ENGINE = INNODB
  82. AUTO_INCREMENT = 105
  83. DEFAULT CHARACTER SET = utf8;
  84.  
  85. CREATE INDEX `fk_t_images_ima_t_stylo_sty1` ON `stylos_promo_2`.`t_images_ima` (`sty_id` ASC) ;
  86.  
  87.  
  88. -- -----------------------------------------------------
  89. -- Table `stylos_promo_2`.`t_matiere_mat`
  90. -- -----------------------------------------------------
  91. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_matiere_mat` (
  92. `mat_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  93. `mat_code` VARCHAR(64) NOT NULL ,
  94. `mat_libelle` VARCHAR(255) NOT NULL ,
  95. PRIMARY KEY (`mat_id`) )
  96. ENGINE = INNODB
  97. AUTO_INCREMENT = 3
  98. DEFAULT CHARACTER SET = utf8;
  99.  
  100.  
  101. -- -----------------------------------------------------
  102. -- Table `stylos_promo_2`.`t_packaging_pac`
  103. -- -----------------------------------------------------
  104. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_packaging_pac` (
  105. `pac_id` INT(5) NOT NULL AUTO_INCREMENT ,
  106. `code_packaging` INT(10) NOT NULL ,
  107. `packaging` VARCHAR(75) CHARACTER SET 'latin1' NOT NULL ,
  108. PRIMARY KEY (`pac_id`) )
  109. ENGINE = INNODB
  110. DEFAULT CHARACTER SET = utf8;
  111.  
  112.  
  113. -- -----------------------------------------------------
  114. -- Table `stylos_promo_2`.`t_piece_pie`
  115. -- -----------------------------------------------------
  116. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_piece_pie` (
  117. `pie_id` INT NOT NULL AUTO_INCREMENT ,
  118. `pie_code` VARCHAR(64) NOT NULL ,
  119. `pie_libelle` VARCHAR(64) NOT NULL ,
  120. `cou_id` INT(10) UNSIGNED NOT NULL ,
  121. `mat_id` INT(10) UNSIGNED NOT NULL ,
  122. PRIMARY KEY (`pie_id`) ,
  123. CONSTRAINT `fk_t_piece_pie_t_couleur_cou1`
  124. FOREIGN KEY (`cou_id` )
  125. REFERENCES `stylos_promo_2`.`t_couleur_cou` (`cou_id` )
  126. ON DELETE NO ACTION
  127. ON UPDATE NO ACTION,
  128. CONSTRAINT `fk_t_piece_pie_t_matiere_mat1`
  129. FOREIGN KEY (`mat_id` )
  130. REFERENCES `stylos_promo_2`.`t_matiere_mat` (`mat_id` )
  131. ON DELETE NO ACTION
  132. ON UPDATE NO ACTION)
  133. ENGINE = INNODB;
  134.  
  135. CREATE INDEX `fk_t_piece_pie_t_couleur_cou1` ON `stylos_promo_2`.`t_piece_pie` (`cou_id` ASC) ;
  136.  
  137. CREATE INDEX `fk_t_piece_pie_t_matiere_mat1` ON `stylos_promo_2`.`t_piece_pie` (`mat_id` ASC) ;
  138.  
  139.  
  140. -- -----------------------------------------------------
  141. -- Table `stylos_promo_2`.`t_stylo_sty_has_t_piece_pie`
  142. -- -----------------------------------------------------
  143. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_stylo_sty_has_t_piece_pie` (
  144. `sty_id` INT(10) UNSIGNED NOT NULL ,
  145. `pie_id` INT NOT NULL ,
  146. PRIMARY KEY (`sty_id`, `pie_id`) ,
  147. CONSTRAINT `fk_t_stylo_sty_has_t_piece_pie_t_stylo_sty`
  148. FOREIGN KEY (`sty_id` )
  149. REFERENCES `stylos_promo_2`.`t_stylo_sty` (`sty_id` )
  150. ON DELETE NO ACTION
  151. ON UPDATE NO ACTION,
  152. CONSTRAINT `fk_t_stylo_sty_has_t_piece_pie_t_piece_pie`
  153. FOREIGN KEY (`pie_id` )
  154. REFERENCES `stylos_promo_2`.`t_piece_pie` (`pie_id` )
  155. ON DELETE NO ACTION
  156. ON UPDATE NO ACTION)
  157. ENGINE = INNODB
  158. DEFAULT CHARACTER SET = utf8;
  159.  
  160. CREATE INDEX `fk_t_stylo_sty_has_t_piece_pie_t_stylo_sty` ON `stylos_promo_2`.`t_stylo_sty_has_t_piece_pie` (`sty_id` ASC) ;
  161.  
  162. CREATE INDEX `fk_t_stylo_sty_has_t_piece_pie_t_piece_pie` ON `stylos_promo_2`.`t_stylo_sty_has_t_piece_pie` (`pie_id` ASC) ;
  163.  
  164.  
  165. -- -----------------------------------------------------
  166. -- Table `stylos_promo_2`.`t_stylo_sty_has_t_packaging_pac`
  167. -- -----------------------------------------------------
  168. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_stylo_sty_has_t_packaging_pac` (
  169. `sty_id` INT(10) UNSIGNED NOT NULL ,
  170. `pac_id` INT(5) NOT NULL ,
  171. PRIMARY KEY (`sty_id`, `pac_id`) ,
  172. CONSTRAINT `fk_t_stylo_sty_has_t_packaging_pac_t_stylo_sty1`
  173. FOREIGN KEY (`sty_id` )
  174. REFERENCES `stylos_promo_2`.`t_stylo_sty` (`sty_id` )
  175. ON DELETE NO ACTION
  176. ON UPDATE NO ACTION,
  177. CONSTRAINT `fk_t_stylo_sty_has_t_packaging_pac_t_packaging_pac1`
  178. FOREIGN KEY (`pac_id` )
  179. REFERENCES `stylos_promo_2`.`t_packaging_pac` (`pac_id` )
  180. ON DELETE NO ACTION
  181. ON UPDATE NO ACTION)
  182. ENGINE = INNODB
  183. DEFAULT CHARACTER SET = utf8;
  184.  
  185. CREATE INDEX `fk_t_stylo_sty_has_t_packaging_pac_t_stylo_sty1` ON `stylos_promo_2`.`t_stylo_sty_has_t_packaging_pac` (`sty_id` ASC) ;
  186.  
  187. CREATE INDEX `fk_t_stylo_sty_has_t_packaging_pac_t_packaging_pac1` ON `stylos_promo_2`.`t_stylo_sty_has_t_packaging_pac` (`pac_id` ASC) ;
  188.  
  189.  
  190. -- -----------------------------------------------------
  191. -- Table `stylos_promo_2`.`t_prixstylos_prx`
  192. -- -----------------------------------------------------
  193. CREATE TABLE IF NOT EXISTS `stylos_promo_2`.`t_prixstylos_prx` (
  194. `prx_id` INT NOT NULL AUTO_INCREMENT ,
  195. `prx_prixunitaire` DECIMAL(8,4) NULL ,
  196. `prx_quantite` INT NULL ,
  197. `prx_ha` DECIMAL(8,4) NULL ,
  198. `mauvais` INT NULL ,
  199. `sty_id` INT(10) UNSIGNED NOT NULL ,
  200. `prx_print` VARCHAR(45) NULL ,
  201. PRIMARY KEY (`prx_id`) ,
  202. CONSTRAINT `fk_t_prixstylos_prx_t_stylo_sty1`
  203. FOREIGN KEY (`sty_id` )
  204. REFERENCES `stylos_promo_2`.`t_stylo_sty` (`sty_id` )
  205. ON DELETE NO ACTION
  206. ON UPDATE NO ACTION)
  207. ENGINE = INNODB;
  208.  
  209. CREATE INDEX `fk_t_prixstylos_prx_t_stylo_sty1` ON `stylos_promo_2`.`t_prixstylos_prx` (`sty_id` ASC) ;
  210.  
  211.  
  212.  
  213. SET SQL_MODE=@OLD_SQL_MODE;
  214. SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
  215. SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

 

 

 

 
Par Cyrano -  Le 10/11/2010 - 

Normal, tu dois essayer de rejouer le même script par dessus la base déjà installée : or les index sont toujours présents, donc impossibles à écraser. En début de script, ajoute ceci :

  1. DROP SCHEMA IF EXISTS `stylos_promo_2`;

Et relance.

Un détails sur tes noms de tables : les tables reationnelles devraient être préfixées « r_ » : même dans MWB tu peux les renommer. essaye de raccourcir certains noms en tentant de leur donner un nom plus significatif et surtout moins barbare : par exemple r_sty_has_pac_shp au lieu de t_stylo_sty_has_t_packaging_pac où tu as lepréfixe d'une table relationelle, le trigramme de chaque table séparé par un has et un suffixe qui pourra servir si tu souhaites ajouter des colonnes dans cette table, suffixe composé de la première lettre de chaque table plus le « h » de « _has_ »

 

 

 
Par paintbox -  Le 11/11/2010 - 

Bonjour Cyrano,

 

j'ai ajouté comme conseillé le "Drop Shema…" et cela fonctionne.

 j'ai donc à présent créé la DB dans Phpmyadmin et fait quelques corrections.

Je voudrais à présent synchroniser mon shéma dans MWB avec ma base SQL modifiée. J'ai créé dans MWB une connexion avec le serveur (local) mais je ne vois pas comment faire pour que mon shéma s'adapte à ma base modifiée?

 

 
Par paintbox -  Le 11/11/2010 - 

Oups j'ai trouvé.

Merci ! 

 

 
Par paintbox -  Le 11/11/2010 - 

Bonjour Cyrano,

voilà ma base est correctement créée, j'ai créé une vue tout cela via MWB. J'ai trouvé la synchronisation PHPmyadmin <=> MWB.

 Il me reste quelques questions:

 

  • La vue que j'ai créé dans MWB est-elle sensée apparaître dans PhpMyAdmin?
  • j'ai essayé de faire une requete tout simple sur ma vue "SELECT * FROM v_stylos" mais il me dit qu'il ne trouve pas la table "'stylos_promo_2'.'v_stylos'"
Peux-tu m'éclairer à ce niveau?
 
Merci 

 

 

 
Par Cyrano -  Le 11/11/2010 - 

Normalement, une vue aparaît au même titre qu'une table. Cependant, on ne peut pas y faire de requête en écriture. Si tu ne la vois pas dans phpMyAdmin, c'est qu'elle n'a pas été créée. Vérifie ton script de création généré dans MWB : si la création de la vue est bien là, vérifie dans la liste de synchronisation qu'elle est bien présente. À la fin de la synchro, il se peut qu'il y ait des erreurs : tupeux les faire afficher et il est possible que le code de la vue soit invalide. Teste ce code de création de vue dans le volet SQL de phpMyAdmin, tu auras peut-être des informations plus précises.

 

 
Par paintbox -  Le 11/11/2010 - 

Ma vue est créé et intégrée dans PHPMysql.

Par contre, cette vue ne devrait-elle pas contenir un résultat?

 

J'ai un autre soucis. J'ai du mal à voir clair avec la table piece.

 On avait établit que :

  • Une pièce a une (et une seule ?) couleur;
  • une pièce est faite d'une (et une seule ?) matière;
  • Une couleur peut concerner 0 à n pièces;
  • Une matière peut constituer 0 à n pièces

mais une pièce peut avoir toutes les couleurs possibles idem pour les matières.

Dans ma table t_piece_pie qui comprend (pie_id, pie_code, pie_libelle, cou_id, mat_id)

je vais avoir  les lignes suivantes :

 pie_id pie_code pie_libelle cou_id mat_id

1 1000 Corps 4 10

2 1100 Clip 3 2

3 1000 Corps 2 5

4 1300 Bagque 5 2

 

et ceci pour toutes les combinaisons de pièces avec couleur et matière?

 

 

 
Par Cyrano -  Le 11/11/2010 - 

Est-ce que ça ne te semble pas logique ? Tu n'as pas tout à fait tort en réalité. On est parti sur ce principe qu'une pièce est d'une et d'une seule couleur, mais le même modèle de pièce peut effectivement exister en différentes couleurs.

Donc en fin de compte, on devrait avoir une relation « [piece] 1:n --- 0:n [couleur] » dans le modèle conceptuel. Même chose pour la relation pièces/matières : ce qui va donc nous faire aboutir dans le modèle physique à deux tables relationnelles supplémentaires.

Mais si ce qui ferait pencher vers la version actuelle, c'est peut-être un élément que j'ignore : chaque pièce a un numéro de référence qui lui est strictement propre : est-ce que ce code tient compte uniquement du modèle de pièce ou bien tient également compte de la matière et de la couleur ? 

 
Par paintbox -  Le 11/11/2010 - 

Dans mon idée de départ, je pensais faire une table pièce qui contient par exemple 5 types de pièces, une table couleur qui contient par ex 10 couleurs et une table matière qui comprend par ex 5 matières chaque fois avec un code propre. 

Puis regroupé le tout dans une table qui donnerait

STY_ID PIE_ID COU_ID MAT_ID

1 1000 2000 1100

1 2000 1000 1200

1 3000 3000 1000

2 1000 4000 1000

2 2000 3000 1300

2 3000 1000 1200 

 
Par Cyrano -  Le 11/11/2010 - 

Ton regroupement, c'est assez exactement l'intérêt de la vue. Mais ça ne répond pas exactement à ma dernière question concernant le référencement des pièces : je reformule autrement. Pour un même modèle de pièce, si la couleur et/ou la matière change, est-ce que le numéro de référence change ? En fait, pose-toi cette question : à partir de la réponse, tu devrais logiquement voir comment doivent être structurés tes éléments.

Ce qu'on doit éviter, ce sont les doublons, les redondances de données, et éviter tout autant les colonnes avec des valeurs NULL. 

 
Par paintbox -  Le 11/11/2010 - 

Je dirais que cela ne sert à rien d'avoir une même pièce déclinée dans chacune des couleurs et des matières. Cela va surcharger inutilement.

Pourquoi je n'aurais pas mes tables Stylo, Pièces, Couleur et Matières

puis une table qui reprend le tout et ou j'aurais par ex:

ID_STYLO   ID_PIECE ID_COULEUR ID_MATIERE

1 1000 1300 2000

1 1200 1100 3000

2 1000 1100 4000

 

Donc à chaque fois l'id du stylo repris autant de fois qu'il comporte de pièces, de couleur et de matières?

 

 

 
Par Cyrano -  Le 11/11/2010 - 

C'est ce que je t'ai mentionné tout à l'heure, mais un doute me vient : as-tu saisi à quoi sert une vue ?

 
Par paintbox -  Le 11/11/2010 - 

non je  crois que je n'ai pas bien saisi alors. La vue est sensée m'amener à cette solution là?

 
Par Cyrano -  Le 11/11/2010 - 

Le principe de la vue, c'est qu'on crée en quelque sorte une table virtuelle à partir d'une requête.

Celle que j'ai suggéré va regrouper dans une même table les éléments des stylos, pièces, couleurs et matières. Si tu fais un DESC de ta vue, tu auras la même structure qu'une table avec la liste des colonnes. Une requête SELECT dans cette vue va te ramener les données qui y seront récupérées via la requête de création de la vue.

Si tu regardes bien ce code, tu vois un CREATE VIEW ... AS « la requête SQL de regroupement »

Tu n'as plus à te torturer les méninges sur des jointures complexes pour récupérer tes données, elles sont déjà dans la vue. Autre point que j,ai aussi déjà indiqué, tu ne peux pas faire de requête INSERT ou UPDATE sur une vue, tout simplement parce qu'en pratique, ce n'est pas réellement une table. Tu n'as pas à te soucier de faire des mises à jours sur la vue, celles faites sur les tables stylos, pièces, couleurs et matières seront automatiquement relayées dans les données de la vue.

Donc tes insertions se font dans les tables « normales », les mises à jour aussi, mais il peut être beaucoup plus pratique de faire les requêtes de sélection sur la vue. Rien n'interdit d'avoir des clauses de tri dans un SELECT sur une vue exactement comme sur une table conventionnelle avec des clauses WHERE, HAVING, ORBER BY, GROUP BY, LIMIT etc... Tu pourrais même faire une jointure entre la vue et d'autres tables ou vues. 

 
Par paintbox -  Le 11/11/2010 - 

ok, mais j'ai du mal à voir où se font mes liens donc

STYLO 1 avec PIECE 1000 dont la COULEUR est 2000 et la MATIERE 1100

Cela se fait dans ma table t_piece_pie ? 

 
Par Cyrano -  Le 11/11/2010 - 

On a séparé les entité pour réduire les redondances. Le montage de tel stylo avec telle pièce de telle couleur et de telle matière se retrouve par jointure avec les clé étrangères. L'idée de tout récupérer dans une seule table se fait en utilisant soit une requête avec un certain nombre de jointures, soit sur une vue qui fait sensiblement la même chose.

Relis la requête SELECT faite pour la création de la vue : qu'est-ce que tu y vois et qu'est-ce que ça va te retourner ? Est-ce que ce n'est pas précisément ce que tu cherches à obtenir ?

 
Par paintbox -  Le 11/11/2010 - 

Ce serait dans part la relation r_stylo_has_piece_shp que je lie le stylo à un pièce,

puis par t_piece_pie je lie une piece à une couleur et une matière.

 

Puis le tout se retrouve dans ma vue? 

 
Par paintbox -  Le 12/11/2010 - 

Bonjour Cyrano,

j'ai toujours un soucis au niveau des pièces (désolé). Je n'ai pas de table qui définit les différentes pièces qui composent un stylo (comme c'est le cas pour couleur et matière).

Si je suis la logique de mon dernier message de hier, tout fonctionne jusqu'à la table t_piece_pie. Là je suis bloqué parce que c'est dans cette table que je lie les pièces aux couleurs et matières. Mais c'est aussi là que je définit mes codes pièces + leur nom respectif. Donc j'en reviens au fait que je vais me retrouvé avec x lignes qui sont la combinaison de chacune de mes pièces x chacune des couleur x chacune des matières.

La vue ne fait que me retourner le résultat de ma requête sur les différentes tables? Elle ne fait qu'interroger les tables selon la requête demandée?

 
Par Cyrano -  Le 12/11/2010 - 

Est-ce que tu as testé avant de poser la question ?? Parce que si tu ne testes pas du tout, ça va limiter pas mal tes possibilités d'une part et ensuite j'aurai l'impression de parler à un mur... D'autant que je t'ai bien expliqué tous les éléments en détail. Si tu lis en diagonale sans t'arrêter sur certains points pourtant importants, je perds mon temps.

 

 
Par paintbox -  Le 12/11/2010 - 

Désolé Cyrano  si je prends ton temps. Les vues sont pour moi quelques chose de nouveau.

J'ai relu les explications que tu m'as donnés jusqu'à présent. 

J'ai également repris le tutorial "Mysql 5.0 : Les vues" de ce site.

J'ai refais l'exemple donnée Produits/Devises/TVA.

Dans cet exemple, a chaque fois que je créé un nouveau produit, les différentes vues (Produit_France,  Produit_France_Dollars…) se mettent à jour. 

J'ai donc essayé la même chose sur ma base et ai complété les tables couleur et matière avec leur code et nom respectif.

J'ai complété les tables r_stylo_has_piece_shp et t_piece_pie mais rien n'apparait dans ma vue.

Il doit y avoir quelque chose que je ne saisi pas. 

 
Par Cyrano -  Le 12/11/2010 - 

Ok, ça signifie donc que la requête SELECT de la vuene retourne rien, ce qui implique que les conditions de jointure ne sont pas remplies.

As-tu testé la requête SELECT de la vue seule, indépendamment de la vue elle-même ? Si oui, obtiens-tu des résultats ? À mon avis non. Donc il manque des données : peut-être manque-t-il des données liant certaines tables dans les tables relationnelles ? Si c'est le cas, il ne faut pas chercher plus loin, ça veut dire que les données n'étant pas liées, aucun retour ne peut être obtenudans la vue.

Là je ne peux pas le savoir sans plus d'éléments : il faudrait le modèle de données exact et le jeu d'essai que tu as introduit dans tes tables. Mais vérifie ça avant.

 

 
Par paintbox -  Le 12/11/2010 - 

Oui en effet, je n'avais pas complété une table (t_prixunitaire) dont des éléments interviennent dans ma vue. Ce devait être cela qui faisait que rien n'apparaissait dans ma vue. J'ai cherché entre temps sur le net et ai lu que si des élément de la vue manquaient, rien ne s'affichait.

 

Je commence tout doucement à comprendre l'usage des vues et leur intérêt (pas trop tot :-(  ).  Mais je crois que je devrais spliter ma vue en 2 vues différentes suivant l'usage dont je veux en faire.

Si je résume dans mon cas, je fais une vue qui regroupe toutes les données dont j'aurai besoin sur ma page web.

Puis sur cette page je fais x requêtes sur la vue selon ce dont j'ai besoin.

Exemple : si je veux afficher les caractéristiques d'un stylo càd (sa longueur, la couleur du corps, la couleur du clip, la matière du corps, la matière du clip…) toutes ces infos sont regroupées dans ma vue et je vais faire une requete sur ma vue en demandant " sort moi pour le stylo '1' la couleur du corps, sa matière et la couleur du clip "

Est-ce exacte ?

 

Je crois que ce qui me perturbait c'est que c'est une autre façon de travailler et de préparer ses tables que ce que je faisais jusqu'à présent. 

 

 

 
Par Cyrano -  Le 13/11/2010 - 

Voilà, tu as effectivement bien cerné la question.

En principe, on crée les vues à partir des tables une fois ces dernières prêtes et à partir des informations qu'elles contiennent selon le besoin dans un but de simplification des requêtes courantes. Selon tes besoins, tu peux avoir différentes vues. Dans chaque vue, tu récupères les informations nécessaires à l'affichage et celles nécessaires à une mise à jour par exemple. Même si tu ne les affiches pas, les identifiant des éléments sont nécessaires pour pouvoir déterminer sur quelle table on doit effectuer une modification. C'est pour ça que la vue que j'ai proposé comporte toutes les colonnes des tables concernées.

Sur une petite base comme celle-ci, c'est peut-être exagéré d'utiliser des vues. Mais bien en maitriser le fonctionnement te sera très utile lorsque tu travailleras sur des bases beaucoup plus importantes et surtout lorsqu'on doit travailler à plusieurs sur une même base : un seul responsable met au point les vues et les développeurs font leurs requêtes SELECT dessus sans devoir se creuser les méninges sur des jointures tordues. Cependant, ça ne dispense pas de la nécessité pour tous de connaître la structure du modèle de données puisque les requêtes en écriture ne se font que sur les tables et non sur les vues.

 
Par paintbox -  Le 13/11/2010 - 

Ouf pas évident de saisir directement l'utilité.  Merci pour ton aide en tout cas.

Par contre d'après ce que j'ai remarqué, une vue ne peut pas évoluer je veux dire par là qu'une fois qu'elle est céée, on ne peut plus ajouter de nouveaux champs? Il faut recréer la vue si on a oublié un champs.

Est-ce exacte?

 

 
Par Cyrano -  Le 13/11/2010 - 

La vue est le reflet d'une requête SQL : si tu veux modifier cette vue par l'ajout ou le retrait d'une colonne, il te suffit de la recréer en modifiant la requête en conséquence, et donc au lieu de CREATE VIEW.., tu devras faire CREATE OR REPLACE VIEW ... et à l'exécution, la vue sera reconstruite.

Mais attention : n'oublie pas qu'une partie de ton code peut être basé sur une version de la vue qui deviendra obsolète après la modification. Gare aux bugs de régression. C'est pourquoi il est important de récupérer le maximum d'informations sur les tables utilisées dans la vue, ça limite les risques d'un manque de données. L'astuce pour faire ce genre de chose, c'est de créer une nouvelle vue en parallèle et de remplacer progressivement les appels faits sur l'ancienne sans bloquer le fonctionnement total de ton application si la vue est massivement utilisée. Lorsque tous les remplacements sont terminés, tu peux alors supprimer la vue d'origine. Comme elle n'est plus utilisée, ça n'affectera nullement les performances.

Il y a en effet un détail à ne pas oublier : une vue, c'est une requête, donc celle-ci est exécutée à chaque fois qu'on y fait appel. Donc, c'est certes très pratique, mais il faut en user avec mesure. Juste au cas où ce détail t'aurait échappé, une vue, c'est comme si on faisait quelque chose comme ceci :

  1. SELECT colonne_x, colonne_y, colonne_z
  2. FROM (
  3. SELECT x.colonne_x, x.colonne_y, y.colonne_z
  4. FROM table_y x
  5. INNER JOIN table_y y ON x.t1_id = y.t1_id
  6. );

 

 Un SELECT sur un autre SELECT. Une requête SELECT retourne un tableau de données, exactement comme une table, donc avec des noms de colonnes et des lignes de données. La vus t'évite justement de faire ce genre de chose en séparant les requêtes. Rien ne t'interdit dans la vue d'utiliser des alias pour tes noms de colonnes, et dans ce cas, la requête SELECT qui pointera sur la vue devra récupérer les alias et non les noms originaux des colonnes. Exemple :

  1. SELECT
  2. colonne_x,
  3. colonne_y,
  4. colonne_z
  5. FROM (
  6. SELECT
  7. t1.macolonne_1 AS colonne_x,
  8. t1.macolonne_2 AS colonne_y,
  9. t2.macolonne_3 AS colonne_z
  10. FROM table_y t1
  11. INNER JOIN table_y t2 ON t1.t1_id = t2.t1_id
  12. );

 

 Est-ce que tu visualises bien le lien entre cette manière de faire et la vue ?

 

 

 
Par paintbox -  Le 14/11/2010 - 

Bonjour Cyrano,

 

oui je crois saisir le lien.

 

Je suis en train de faire différentes vues. Dont une qui calcule mon prix + un pourcentage. J'y suis parvenu (grace au tutorial Les vues) , mais le résultat (Prix_vente) que j'obtiens est avec 10 chiffres derrière la virgule. Y a-t-il moyen de limiter le nombre de chiffres derrière la virgule?

Je pensais mettre un ,2 après le calcul de mon Prix_vente mais cela ne fonctionne pas.

Voici ma vue: 

  1. CREATE VIEW `stylos_promo_2`.`quan_prix` AS SELECT p.sty_id, p.prx_quantite, p.prx_ha, p.prx_print,
  2. (p.prx_ha + ((p.prx_ha * t_com_com.com_taux)/100)) AS Prix_vente
  3.  
  4. FROM (t_prixstylos_prx p JOIN t_com_com)
  5. INNER JOIN t_stylo_sty s ON p.sty_id = s.sty_id
  6. WHERE t_com_com.com_id='1'

 

 

 
Par Cyrano -  Le 14/11/2010 - 

Gère l'affichage en PHP avec number_format(), ce sera plus simple et plus juste, surtout si tu dois faire d'autrescalculs dessus par la suite.

 

Il existe bien une fonction native FORMAT() dans MySQL mais le formattage de sortie est anglais, alors que number_format en PHP t'offre des possibilités beaucoup plus souples.

 

 
Par paintbox -  Le 14/11/2010 - 

OK merci

 
Par paintbox -  Le 16/11/2010 - 

Hello Cyrano,

 me revoilà.

J'ai avancé sur mon projet, mais je rencontre à nouveau un problème.

J'essaie d'établir un devis à partir de la sélection  par l'utilisateur de différents options (N° d'article, quantité, nombre de couleurs…).

J'ai un problème au niveau du retour de résultat des mes requêtes.

Pour la première, mon image ne s'affiche pas et pour la seconde, mon prix reste à 0.

Hors j'ai testé mes requêtes dans SQLPro et elles fonctionnent. Et si je teste mon code séparément sur une autre page, cela fonctionne aussi.

 Aurais-tu une explication? Ou vois-tu quelques chose qui coince? 

 

J'ai également une autre question à te poser.

J'ai créé dans ma base de  nouvelles vues et quand je fais une requête qui associe plusieurs vues, cela ralenti beaucoup le résultat. Je n'ai d'ailleurs pas de réponse affiché dans mon navigateur alors que la même requête dans SQL Pro fonctionne. Est-ce que l'usage de plusieurs vue est conseillé et est-ce que ça alourdi? 

 

Voici mon code.

Merci pour ton aide 

 

  1. /*Recuperation des donn&eacute;es pour devis*/
  2. $selected_stylo =$_POST['selected_stylo'];
  3. $quantity =$_POST['quantity'];
  4. $prix_quantity =$quantity;
  5. $nb_couleur =$_POST['couleur'];
  6.  
  7. /*Requetes de recherche*/
  8. $request_ref=mysql_query("SELECT s.sty_id, s.sty_reference, s.sty_nom,
  9. i.sty_id, i.ima_chemin,i.ima_rang
  10. FROM t_images_ima i
  11. INNER JOIN t_stylo_sty s ON s.sty_id = i.sty_id
  12. WHERE s.sty_id='.$selected_stylo.' AND i.ima_rang='1'") or die("S&eacute;lection de la base impossible !");
  13.  
  14. $reference =mysql_fetch_assoc($request_ref);
  15. echo $reference['ima_chemin'];
  16.  
  17.  
  18. $prix_quantity=($prix_quantity <5000) ? '5000' :'' ;
  19. $prix_quantity=($prix_quantity >=5000 AND $prix_quantity <=10000) ? 'D&eacute;sol&eacute;, la quantit&eacute; minimale est de 5000 pcs' :'' ;
  20. $prix_quantity=($prix_quantity >=10000 AND $prix_quantity <15000) ? '10000' :'' ;
  21. $prix_quantity=($prix_quantity >=15000 AND $prix_quantity <25000) ? '15000' :'' ;
  22. $prix_quantity=($prix_quantity >=25000) ? '25000' :'' ;
  23. echo '<p>Pour la quantit&eacute; : '.$quantity.'</p>';
  24. echo '<span>Le tarif sera : </span>'.$prix_quantity;
  25. $request_prix=mysql_query("SELECT s.sty_id, s.sty_reference,
  26. qp.prx_quantite, qp.Prix_vente
  27. FROM v_quan_prix qp
  28. INNER JOIN t_stylo_sty s ON qp.sty_id = s.sty_id
  29. WHERE s.sty_id='.$selected_stylo.' AND qp.prx_quantite='.$prix_quantity.'") or die("S&eacute;lection de la base impossible !");
  30. $request_prix =mysql_fetch_assoc($request_prix);
  31. $prix_unitaire =number_format($request_prix['Prix_vente'], 4, ',','.');
  32. echo '<p>Le prix est de : '.$prix_unitaire.'</p>';
  33. echo '<div class="wrapper">';
  34. echo '<p>Ref :'.$selected_stylo.'</p>';
  35. echo $quantity.'<br/>';
  36. echo '<p>Nb couleurs : '.$nb_couleur.'</p>';
  37. /*Tableau DEVIS*/
  38. echo '<table width="100%" class="table_prix">';
  39. echo '<tr>';
  40. echo '<th>Ref</th>';
  41. echo '<th>Photo</th>';
  42. echo '<th>Quantit&eacute;</th>';
  43. echo '<th>Produit</th>';
  44. echo '<th>Prix Unitaire</th>';
  45. echo '<th>Marquage</th>';
  46. echo '<th>Quantit&eacute; Marquage</th>';
  47. echo '<th>Total HTVA</th>';
  48. echo '</tr>';
  49. echo '<tr>';
  50. echo '<td>'.$reference['sty_reference'].'</td>';
  51. echo '<td><img src="'.$reference['ima_chemin'].'" width="50" height="50"></td>';
  52. echo '<td>'.$quantity.'</td>';
  53. echo '<td>'.$reference['sty_nom'].'</td>';
  54. echo '<td>'.$prix_unitaire.' &euro;</td>';
  55. echo '<td>Marquage</td>';
  56. echo '<td>'.$nb_couleur.'</td>';
  57. /*
  58.   $total=(($quantity * $prix_unitaire)+($quantity*$print));
  59. */
  60. echo '<td>'.$total.' &euro;</td>';
  61. echo '</tr>';
  62. echo '</table>';

 

 

 
Par Cyrano -  Le 16/11/2010 - 

Salut,

les requêtes avec des jointures sur des vues est un peu sans intérêt : c'est justement à ça que servent les vues, ne pas devoir faire de requêtes complexe. Si tu as régulièrement besoin d'une collection de données devant faire appel à différentes tables, crée une vue qui intègre les jointures sur toutes ces tables et ensuite tu fais un simple SELECT sur cette vue.

 Pour le reste, ton code est un peu pénible à lire parce que pas très aéré. Et je tesignale que faire une indentation sur une suite d'instructions echo() ne mettra pas d'intentation dans le code de sortie qui sera illisible lorsque tu voudra faire afficher la source HTML dans ton navigateur.

Ensuite, tu me dis avoir testé tes requêtes dans SQLPro... soit, mais ça veut dire que tu as fait du copier/collé à partir du code et non pas de l'affichage d'une requête générée. Voici un petit nettoyage du code, note les modifications et regarde comment faire afficher tes requêts pour le tester : comme il y a des valeurs dynamiques dedans, il est important que tu vérifie que ce qui est généré est valide :

  1. <?php
  2. /*Recuperation des donn&eacute;es pour devis*/
  3. $selected_stylo = $_POST['selected_stylo'];
  4. $quantity = $_POST['quantity'];
  5. $prix_quantity = $quantity;
  6. $nb_couleur = $_POST['couleur'];
  7.  
  8. /*Requetes de recherche*/
  9. $sql = "SELECT ".
  10. " s.sty_id, ".
  11. " s.sty_reference, ".
  12. " s.sty_nom, ".
  13. " i.sty_id, ".
  14. " i.ima_chemin, ".
  15. " i.ima_rang ".
  16. "FROM t_images_ima i ".
  17. " INNER JOIN t_stylo_sty s ON s.sty_id = i.sty_id ".
  18. "WHERE s.sty_id = '. $selected_stylo .' ".
  19. " AND i.ima_rang = 1";
  20. echo("<pre>Première requête :\n");
  21. var_dump($sql);
  22. echo("</pre>\n");
  23. $request_ref = mysql_query($sql) or die("S&eacute;lection de la base impossible !");
  24.  
  25. $reference = mysql_fetch_assoc($request_ref);
  26. echo $reference['ima_chemin'];
  27.  
  28. $prix_quantity = ($prix_quantity < 5000) ? '5000' : '' ;
  29. $prix_quantity = ($prix_quantity >= 5000 && $prix_quantity <= 10000) ? 'D&eacute;sol&eacute;, la quantit&eacute; minimale est de 5000 pcs' :'' ;
  30. $prix_quantity = ($prix_quantity >= 10000 && $prix_quantity < 15000) ? '10000' :'' ;
  31. $prix_quantity = ($prix_quantity >= 15000 && $prix_quantity < 25000) ? '15000' :'' ;
  32. $prix_quantity = ($prix_quantity >= 25000) ? '25000' : '' ;
  33.  
  34. $sql2 = "SELECT ".
  35. " s.sty_id, ".
  36. " s.sty_reference, ".
  37. " qp.prx_quantite, ".
  38. " qp.Prix_vente ".
  39. "FROM v_quan_prix qp ".
  40. " INNER JOIN t_stylo_sty s ON qp.sty_id = s.sty_id ".
  41. "WHERE s.sty_id = '.$selected_stylo.' ".
  42. " AND qp.prx_quantite = '. $prix_quantity .'";
  43. echo("<pre>Seconde requête :\n");
  44. var_dump($sql2);
  45. echo("</pre>\n");
  46. $request_prix = mysql_query($sql2) or die("S&eacute;lection de la base impossible !");
  47. $request_prix = mysql_fetch_assoc($request_prix);
  48. $prix_unitaire = number_format($request_prix['Prix_vente'], 4, ',','.');
  49.  
  50. $sortie = <<<CODE_HTML
  51. <p>Pour la quantit&eacute; : {$quantity}</p>
  52. <span>Le tarif sera : </span>{$prix_quantity}
  53. <p>Le prix est de : {$prix_unitaire}</p>
  54. <div class="wrapper">
  55. <p>Ref :{$selected_stylo}</p>
  56. {$quantity}<br/>
  57. <p>Nb couleurs : {$nb_couleur}</p>
  58. <table width="100%" class="table_prix">
  59. <tr>
  60. <th>Ref</th>
  61. <th>Photo</th>
  62. <th>Quantit&eacute;</th>
  63. <th>Produit</th>
  64. <th>Prix Unitaire</th>
  65. <th>Marquage</th>
  66. <th>Quantit&eacute; Marquage</th>
  67. <th>Total HTVA</th>
  68. </tr>
  69. <tr>
  70. <td>{$reference['sty_reference']}</td>
  71. <td><img src="{$reference['ima_chemin']}" width="50" height="50" /></td>
  72. <td>{$quantity}</td>
  73. <td>{$reference['sty_nom']}</td>
  74. <td>{$prix_unitaire} &euro;</td>
  75. <td>Marquage</td>
  76. <td>{$nb_couleur}</td>
  77. <td>{$total} &euro;</td>
  78. </tr>
  79. </table>
  80.  
  81. CODE_HTML;
  82. echo $sortie;

Essaye comme ça.

Et au passage, si le sujet original de ce post est résolu, pour les prochaines questions, ouver un nouveau post, ça reste un forum, pas un chat ;)

 

 

 
Par Cyrano -  Le 16/11/2010 - 

Petite erreur dans les concaténations des requêtes SQL, corrigé :

  1. <?php
  2. /*Recuperation des donn&eacute;es pour devis*/
  3. $selected_stylo = $_POST['selected_stylo'];
  4. $quantity = $_POST['quantity'];
  5. $prix_quantity = $quantity;
  6. $nb_couleur = $_POST['couleur'];
  7.  
  8. /*Requetes de recherche*/
  9. $sql = "SELECT ".
  10. " s.sty_id, ".
  11. " s.sty_reference, ".
  12. " s.sty_nom, ".
  13. " i.sty_id, ".
  14. " i.ima_chemin, ".
  15. " i.ima_rang ".
  16. "FROM t_images_ima i ".
  17. " INNER JOIN t_stylo_sty s ON s.sty_id = i.sty_id ".
  18. "WHERE s.sty_id = '". $selected_stylo ."' ".
  19. " AND i.ima_rang = 1";
  20. echo("<pre>Première requête :\n");
  21. var_dump($sql);
  22. echo("</pre>\n");
  23. $request_ref = mysql_query($sql) or die("S&eacute;lection de la base impossible !");
  24.  
  25. $reference = mysql_fetch_assoc($request_ref);
  26. echo $reference['ima_chemin'];
  27.  
  28. $prix_quantity = ($prix_quantity < 5000) ? '5000' : '' ;
  29. $prix_quantity = ($prix_quantity >= 5000 && $prix_quantity <= 10000) ? 'D&eacute;sol&eacute;, la quantit&eacute; minimale est de 5000 pcs' :'' ;
  30. $prix_quantity = ($prix_quantity >= 10000 && $prix_quantity < 15000) ? '10000' :'' ;
  31. $prix_quantity = ($prix_quantity >= 15000 && $prix_quantity < 25000) ? '15000' :'' ;
  32. $prix_quantity = ($prix_quantity >= 25000) ? '25000' : '' ;
  33.  
  34. $sql2 = "SELECT ".
  35. " s.sty_id, ".
  36. " s.sty_reference, ".
  37. " qp.prx_quantite, ".
  38. " qp.Prix_vente ".
  39. "FROM v_quan_prix qp ".
  40. " INNER JOIN t_stylo_sty s ON qp.sty_id = s.sty_id ".
  41. "WHERE s.sty_id = '". $selected_stylo ."' ".
  42. " AND qp.prx_quantite = '". $prix_quantity;
  43. echo("<pre>Seconde requête :\n");
  44. var_dump($sql2);
  45. echo("</pre>\n");
  46. $request_prix = mysql_query($sql2) or die("S&eacute;lection de la base impossible !");
  47. $request_prix = mysql_fetch_assoc($request_prix);
  48. $prix_unitaire = number_format($request_prix['Prix_vente'], 4, ',','.');
  49.  
  50. $sortie = <<<CODE_HTML
  51. <p>Pour la quantit&eacute; : {$quantity}</p>
  52. <span>Le tarif sera : </span>{$prix_quantity}
  53. <p>Le prix est de : {$prix_unitaire}</p>
  54. <div class="wrapper">
  55. <p>Ref :{$selected_stylo}</p>
  56. {$quantity}<br/>
  57. <p>Nb couleurs : {$nb_couleur}</p>
  58. <table width="100%" class="table_prix">
  59. <tr>
  60. <th>Ref</th>
  61. <th>Photo</th>
  62. <th>Quantit&eacute;</th>
  63. <th>Produit</th>
  64. <th>Prix Unitaire</th>
  65. <th>Marquage</th>
  66. <th>Quantit&eacute; Marquage</th>
  67. <th>Total HTVA</th>
  68. </tr>
  69. <tr>
  70. <td>{$reference['sty_reference']}</td>
  71. <td><img src="{$reference['ima_chemin']}" width="50" height="50" /></td>
  72. <td>{$quantity}</td>
  73. <td>{$reference['sty_nom']}</td>
  74. <td>{$prix_unitaire} &euro;</td>
  75. <td>Marquage</td>
  76. <td>{$nb_couleur}</td>
  77. <td>{$total} &euro;</td>
  78. </tr>
  79. </table>
  80.  
  81. CODE_HTML;
  82. echo $sortie;

 

 

 

 
Par paintbox -  Le 16/11/2010 - 

Merci pour ta aide.

 

J'ai quelques questions. Désolé si elles sont un peu stupides.

1- Pourquoi fais-tu des concaténations dans les 2 requêtes? Quel est l'intérêt? Pour ma part, j'ai l'habitude de les faire en continu (donc sans concaténation).

2-  Je ne comprends pas ton "$sortie = <<<CODE_HTML" et ta façon d'afficher les résultats de requête "<p>Le prix est de : {$prix_unitaire}</p>"

Pourquoi ne fais tu pas <p>Le prix est de :

  1. <?php echo '<p>'.$prix_unitaire.'</p>';

 

 

 

 

 
Par Cyrano -  Le 16/11/2010 - 

Les concaténation, c'est une habitude et ça fait partie des bonnes pratiques. Ne pas le faire, c'est du laxisme. Un jour un copain sur PHPFrance m'a qualifié de « méticuleur de mouches » : j'assume entièrement et complètement ça et je te recommande vivement d'en faire tout autant. C'est une discipline et ça évite bien des problèmes. Tu auras suffisament à faire avec des bugs tordus sans devoir en plus perdre du temps sur des petites erreurs de concaténation.

L'autre point, c'est de la syntaxe HEREDOC, c'est une manière d'écrire des chaines de textes en y insérant des variables. Je te suggère un petit tour dans la doc sur le sujet. Tu auras peut-être tout de même noté que c'est plus propre et beaucoup plus facile à lire, et même à écrire.

Si tu as du mal à t'en servir, pose les questions, mais fais des essais, à mon avis tu vas rapidement y prendre goût ;)

 

 
Par paintbox -  Le 16/11/2010 - 

Je viens de lire le lien que tu m'as transmis. J'avoue que je ne comprend pas trop. C'est assez déroutant.

Je crois que je vais devoir relire cela plusieurs fois. 

Le code tel que tu me l'as mis avec la syntaxe Heredoc ne fonctionne pas. 

Peut-être que je l'utilise mal? 

 
Par Cyrano -  Le 16/11/2010 - 

Attention à certains points lors de l'utilisation de cette syntaxe :

  1. Le mot clé choisi en ouverture doit être strictement le même que le mot de fermeture;
  2. Le mot clé de fermeture doit impérativement être en début de ligne et jamais précédé d'un espace;
  3. Les mot clé d'ouverture doit obligatoirement être suivi par un retour de chariot (\n).
  4. Les mot clé de fermeture doit obligatoirement être précédé par un retour de chariot(\n).

C'est une manière pour encadrer la valeur d'une variable. Jusqu'à maintenant, tu avais l'habitude d'utiliser des paires de guillemets ou d'apostrophes comme ceci :

  1. $maVariable_1 = "Une valeur";
  2. $maVariable_2 = 'Une autre valeur';

Je te montre aujourd'hui une nouvelle manière d'encadrer une chaine. Au lieu d'un guillemet ouvrant, tu utilises un triple chevron ouvrant suivi d'un mot clé. Tu choisi le mot que tu veux, ici j'ai utilisé « CODE_HTML » parce que c'est assez explicite. En respectant les points que je viens de mentionner, ça donne : 

  1. $maVariable_3 = <<<UNE_CHAINE
  2. Une valeur de chaine.
  3. UNE_CHAINE;
    //... suite du code

La coloration syntaxique ici ne fonctionne pas très bien avec cette syntaxe, mais Tu as les éléments. Ça fonctionne depuis la version... j'ai un doute, 4.2 ou 4.3 de PHP, peut-être un peu avant.

Ça, c'est l'exemple vraiment basique, tu as des exemples plus riches dans la doc que je t'ai indiquée. 

 

 
Par paintbox -  Le 16/11/2010 - 

C'est déjà un peu plus clair avec tes explications. Merci

 

Dans un message précédent, tu me disais "les requêtes avec des jointures sur des vues est un peu sans intérêt" . Est-ce que cela vaut aussi pour une vue? Je veux dire par là est ce que pour créer une vue, je ne peu pas faire de jointure avec une autre vue? 

En gros, j'ai déjà la Vue_1 qui existe et je veux créer une Vue_2 dans laquelle je fais une jointure avec la Vue_1 ?

 

Je crains que ta réponse ne soit non on ne peut pas :-( 

 
Par Cyrano -  Le 17/11/2010 - 

Techniquement tu peux tout à fait, mais encore une fois c'est sans intérêt et ça risque fort de ruiner un peu les performances. Il vaut mieux tenter de mettre au point la bonne requête qui va bien pour ta seconde vue, et une requête peut être assez complexe à l'intérieur d'une vue.

 

Ajouter une réponse à la discussion

Seuls les membres loggués sont autorisés à poster dans les forums !