IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Ecriture de requête


Sujet :

PHP & Base de données

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    295
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 295
    Par défaut Ecriture de requête
    Bonjour,

    Je rencontre des difficultés dans l'écriture d'une requête. Il s'agit de récupérer (en autres) des produits pour un bon de commande. Pour ce faire, j'ai trois composants essentiels à prendre en compte :

    les fournisseurs
    les labo(ratoire)s
    Chaque labo a ses sections (CAP, BP, BAC...)

    La table admincom regroupe la totalité des commandes créées. Je dois pouvoir récupérer tous les produits commandé pour chaque fournisseur. Puis indiquer par la suite quel labo a enregistré tels produits pour quelle section. Cela donnerait à l'affichage:
    le fournisseur
    le labo
    la section
    la désignation du produit - la quantité - le conditionnement
    etc.
    la section
    etc.
    labo
    etc.
    Pour l'instant, j'ai écris ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT produits.designation, quantite, section, admincom.idUser, labo, produits.conditionnement 
    FROM produits 
    INNER JOIN admincom ON admincom.designation = produits.designation 
      INNER JOIN users ON admincom.idUser = users.idUser 
    INNER JOIN fournisseurs ON produits.idFrs = fournisseurs.idFrs 
    WHERE fournisseurs.idFrs = 2 
    GROUP BY produits.designation, produits.conditionnement';
    je pense que mes jointures sont bonnes, mais je bloque sur la fin de la requête... Je fais donc appel à vos lumières. En fichier joint se trouve le schéma de la base de données.
    merci,
    Images attachées Images attachées  

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    S'il est encore possible de changer le modèle de données, je vous conseille fortement de le faire !

    D'après ce que je vois :
    - La branche catégories / produits / fournisseurs n'est pas reliée au reste.
    - Sections et conditionnements ne sont pas reliés au reste.
    - Alors que la table 'produits' dispose bien d'une clé primaire idPdts de type entier, il semble que ce soit la désignation du produit (de type TEXT) qui serve de clé étrangère dans les autres tables (admincom, commandes, historique).
    - Idem pour conditionnement dont on retrouve le texte dans le produit.
    - Idem pour section dont on retrouve le texte dans commandes et admincom.
    - Qu'est-ce qui justifie l'existence des trois tables admincom, commandes et historiques qui ont la même structure ou presque ?

    Bref, ce modèle est loin d'être optimisé !

    Ce qu'il faudrait plutôt faire :
    user -0,n----Passer----1,1- commande -1,n----Contenir----0,n- produit

    categorie -0,n----Classer----1,1- produit -1,1----EstFourniPar----0,n- fournisseur

    produit -1,1----Conditionner----0,n- conditionner

    Les laboratoires devraient être externalisés dans une autre table et on aurait les relations :
    user -1,1----Appartenir----0,n- labo -0,n----Avoir----0,n- section

    Il semble alors que la relation entre les user et les commandes devienne une ternaire prenant en compte la section :
    user -0,n----Passer----1,1- commande
    section -0,n----|
    Mais il faudra mettre une contrainte d'inclusion de la section de la commande par rapport à la section du labo de l'utilisateur.

    Tout ce qui précède n'est bien sûr qu'une interprétation de la lecture du schéma que vous fournissez.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    295
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 295
    Par défaut re:
    Hum, je crois que je n'ai pas eu une bonne idée de poster ce schéma... Je l'ai modifié suite à l'importation dans DBDesigner. C'était uniquement l'occasion de découvrir le logiciel et de le manipuler un petit peu... Je ne pense pas effectivement que cette image reflète la base telle qu'elle est. Celle-ci a été créée bien auparavant sous phpMyAdmin.
    Je préfère donc poster pour l'instant un export de la base, avec uniquement les tables qui m'intéressent pour la requête récalcitrante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    -- Base de données: `alimentaires`
     
    -- --------------------------------------------------------
    -- Structure de la table `admincom`
     
    CREATE TABLE IF NOT EXISTS `admincom` (
      `idCom` int(4) NOT NULL AUTO_INCREMENT,
      `designation` text COLLATE utf8_unicode_ci NOT NULL,
      `quantite` decimal(10,1) NOT NULL,
      `section` text COLLATE utf8_unicode_ci NOT NULL,
      `idUser` int(2) NOT NULL,
      PRIMARY KEY (`idCom`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=133 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `categories`
     
    CREATE TABLE IF NOT EXISTS `categories` (
      `idCat` int(2) NOT NULL AUTO_INCREMENT,
      `categorie` text COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`idCat`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=9 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `conditionnement`
     
    CREATE TABLE IF NOT EXISTS `conditionnement` (
      `idCond` int(2) NOT NULL AUTO_INCREMENT,
      `conditionnement` text COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`idCond`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=29 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `fournisseurs`
     
    CREATE TABLE IF NOT EXISTS `fournisseurs` (
      `idFrs` int(2) NOT NULL AUTO_INCREMENT,
      `raisonSociale` text COLLATE utf8_unicode_ci NOT NULL,
      `adresse1` text COLLATE utf8_unicode_ci NOT NULL,
      ...
      PRIMARY KEY (`idFrs`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `produits`
     
    CREATE TABLE IF NOT EXISTS `produits` (
      `idPdts` int(4) NOT NULL AUTO_INCREMENT,
      `designation` text COLLATE utf8_unicode_ci NOT NULL,
      `conditionnement` text COLLATE utf8_unicode_ci NOT NULL,
      `idFrs` int(2) NOT NULL,
      `idCat` int(2) NOT NULL,
      PRIMARY KEY (`idPdts`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=441 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `sections`
     
    CREATE TABLE IF NOT EXISTS `sections` (
      `idSect` int(2) NOT NULL AUTO_INCREMENT,
      `section` text COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`idSect`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ;
     
    -- --------------------------------------------------------
    -- Structure de la table `users`
     
    CREATE TABLE IF NOT EXISTS `users` (
      `idUser` int(2) NOT NULL AUTO_INCREMENT,
      `nom` text COLLATE utf8_unicode_ci NOT NULL,
      `mdp` text COLLATE utf8_unicode_ci NOT NULL,
      `labo` text COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`idUser`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=15 ;
    ps : Auquel cas cette structure ne serait pas optimisée (propre ?), il ne m'est pas possible de la modifier pour l'instant. Nous sommes déjà rentré en production avec... Je prendrais toutefois le temps pour une prochaine version de l'application de soumettre cette structure pour une optimisation.
    Merci,

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    OK. Le message est passé, revenons à la requête...

    Vous faites un GROUP BY alors qu'il n'ya pas de fonction de calcul dans le SELECT. Le GROUP BY est donc inutile.
    Le reste semble correct.

    Un mot cependant qui me ramène à critiquer la structure de la BDD. Vous avez beaucoup de colonnes qui sont de type TEXT alors qu'un VARCHAR aurait été beaucoup plus approprié, notamment parce qu'on ne peut pas mettre d'index sur un type TEXT, ce qui fait que votre jointure ne seront pas du tout performantes.

    J'ai un peu de mal à voir votre besoin :
    Je dois pouvoir récupérer tous les produits commandé pour chaque fournisseur. Puis indiquer par la suite quel labo a enregistré tels produits pour quelle section. Cela donnerait à l'affichage:
    le fournisseur
    le labo
    la section
    la désignation du produit - la quantité - le conditionnement
    etc.
    la section
    etc.
    labo
    etc.
    Votre requête donne la première série d'informations souhaitée pour le fournisseur 2.

    Si vous voulez toutes les commandes classées par fournisseur, puis par labo puis par section, ou tout autre critère de tri, il faut utiliser ORDER BY.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT f.raisonsociale, u.labo, a.section, p.designation, a.quantite, p.conditionnement, a.idUser,  
    FROM produits AS p
    INNER JOIN admincom AS a ON a.designation = p.designation 
      INNER JOIN users AS u ON a.idUser = u.idUser 
    INNER JOIN fournisseurs AS f ON p.idFrs = f.idFrs 
    ORDER BY f.raisonsociale, u.labo, a.section
    J'ai ajouté des alias, c'est plus facile à lire.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    295
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 295
    Par défaut re:
    Bonjour,

    Merci pour la réponse! J'obtiens bien maintenant toutes les données nécessaires... Toutefois, je rencontre un nouveau problème sur l'affichage de celles-ci... Comme indiqué sur le premier post, je dois respecter cette chronologie:
    le labo
    la section
    Tous les produits commandés pour cette section
    --------
    la section
    produits
    --------
    labo
    etc.
    Pour l'instant, j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while($data = mysql_fetch_array($requete)){
     echo $data['labo'].'<br>';
     if(!empty($data['section'])){// si pas de commande pour cette section
      	echo strtoupper($data['section']).'<br>';
     }
     echo $data['designation'].' '.$data['quantite'].' '.$data['conditionnement'].'<br>';
    }
    Et j'obtiens avec ceci:
    Boulangerie Treilles
    CAP
    Lardons fum 3.0 kg
    Boulangerie Treilles
    CAP
    Roquefort 2.0 kg
    Cuisine Langin
    CAP
    Cr 6.0 kilo(s)
    Cuisine Langin
    CAP
    Beurre plaque 250 gr 20.0 pi
    Cuisine Langin
    CAP
    Cr 6.0 litre(s)
    Pour le labo Cuisine/ section CAP, il faudrait que je puisse ranger en dessous de la section CAP Cr 6.0 kilo(s), Beurre plaque 250 gr 20.0 pi...
    Et là, je sèche...
    merci,

  6. #6
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    C'est au programme PHP de s'occuper de la mise en forme.*
    Si je comprends bien, vous souhaitez que n'apparraisse qu'une fois le couple labo/section et en dessous tous les produits commandés par ce couple, avant de passer au couple suivant ?

    Il suffit de mémoriser ce couple dans une variable et de tester si la valeur lue par l'itération en cours de la boucle while est identique à cette variable. Si c'est le cas, on n'affiche pas le couple. Quelque chose du genre :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // Initialisation des variables
    $labo = '';
    $section = '';
     
    // Lecture et traitement des données
    while($data = mysql_fetch_array($requete))
    {
      if($data['labo'] != $labo) // Si on a changé de labo, on l'affiche
      {
        $labo = $data['labo'];
        echo $labo.'<br />';
      }
     
      if($data['section'] != $section; // Si on a changé de section, on l'affiche
      {
        $section = $data['section'];
        echo strtoupper($section).'<br />';
      }
     
      echo $data['designation'].' '.$data['quantite'].' '.$data['conditionnement'].'<br />';
    }
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    295
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 295
    Par défaut [RESOLU]re:
    Tout s'affiche correctement maintenant... Un grand merci à vous!

Discussions similaires

  1. Ecriture de requêtes SQL dans fichier .TXT
    Par Kevfou dans le forum Langage
    Réponses: 11
    Dernier message: 19/10/2011, 17h59
  2. Ecriture requête et performance
    Par chouffe59 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 09/02/2011, 13h45
  3. Aide sur ecriture requête
    Par bruce207 dans le forum Requêtes
    Réponses: 1
    Dernier message: 06/08/2008, 13h38
  4. Problème "conceptuel" de requête SQL (pas dans leurs ecritures)
    Par Julie!!! dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 22/04/2008, 11h25
  5. Ecriture d'une variable dans une requête
    Par papilou86 dans le forum Access
    Réponses: 2
    Dernier message: 02/06/2006, 09h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo