[phpMySQL] - Ecarter les colonnes vides

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par HawkEye, 8 Février 2006.

  1. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    Hello,

    Une question me retourne l'esprit... Si quelqu'un peut me filer un coup de main, ce serait génial.

    Contexte

    Je suis occupé à développer un catalogue de produits, en phpMySQL, pour ma boîte.

    La structure est la suivante:

    1 table "catégories"
    A la manière d'un annuaire, les catégories sont reprises dans une table, et ont chacune un identifiant du style "numéro de catégorie" et "numéro de la catégorie à laquelle celle-ci appartient"...

    1 table "produits"
    Même principe, un produit est un groupe d'articles (j'expliquerai plus bas), qui appartient à une ou plusieurs catégories; la structure est simple, et composée de "id_produit", "appartenance1", "appartenance2", etc...

    Jusque là, c'est assez simple d'afficher des catégories et leurs sous-catégories, et de naviguer jusqu'à une catégorie qui contient des produits, où on finit par

    Code:
    $query = "SELECT * FROM produits WHERE appartenance1 = $categorie OR appartenance2 = $categorie (etc...)
    
    Ma difficulté apparaît ici:

    Pour chaque "produit", il y'a un ou plusieurs "articles" (les références commercialisables).
    Je souhaite grouper tous les articles dans une même table "articles", ce qui jusqu'ici n'est pas complexe...

    Je finis donc avec une requête "SELECT * FROM articles WHERE into_produit = $produit (etc...)"

    Problème

    J'ai énormément de produits différents, et je souhaite afficher des informations techniques qui sont variables.
    Par exemple: pour des cosses électriques, je vais parler de "diamètre", de "couleur", de "section"; alors que pour des lampes je vais parler de "voltage", "wattage", "ampérage", "culot"...

    Sachant que je souhaite que toutes ces données figurent dans une table "articles" unique, je vais utiliser une table contenant un grand nombre de "colonnes", dont une grande partie sera vide...

    Ma question est la suivante:

    Pour chaque "produit", je fais une requête qui me sort la liste des "articles" correspondant à ce "produit". Le résultat pourrait donner (exemple "cosse électrique"):

    REF.0001 | vide | vide | vide | vide | 3.0mm | rouge | 8mm² | vide | vide |

    et pour un autre article (exemple "ampoule"):

    REF.0002 | 12V | 55W | 0.5A | vide | vide | vide | vide | vide | vide |

    Je cherche à n'afficher dans mon résultat QUE les colonnes non-vides, sachant que pour un même produit, on peut aussi avoir un résultat du style...

    REF.0002 | 12V | 55W | 0.5A | vide | vide | vide | vide | vide | vide |
    REF.0003 | 12V | 55W | vide | vide | vide | vide | vide | vide | vide |
    REF.0004 | 12V | vide | vide | vide | vide | vide | vide | vide | vide |

    En gros, afficher un tableau du genre:

    [​IMG]

    bref... j'espère que vous comprenez mon tourment...

    Est-ce que quelqu'un aurait une solution "pratique" et "non-gourmande" ?

    Merci !!![/img]
     
  2. dmathieu
    dmathieu WRInaute accro
    Inscrit:
    9 Janvier 2004
    Messages:
    5 596
    J'aime reçus:
    0
    tu ne peut, en sql, ne selectionner que les requetes non vides (que je sache du moins)
    donc, la seule solution que je verrait, c'est de faire des if avant l'affichage de ton code.

    Code:
    if ($variable != NULL) {
     
  3. Bourriquet
    Bourriquet WRInaute impliqué
    Inscrit:
    19 Septembre 2005
    Messages:
    561
    J'aime reçus:
    0
    Tu peux utiliser un champ Texte et stocker tes données en formattant le champ. Exemple :

    caractéristique1:valeur;caractéristique2:valeur;caractéristique3:valeur;


    Tu te fais une petite fonctione en PHP qui explose la chaine grâce aux séparateurs.

    Et pour la recherche, tu crée un index fulltext sur le champ, et tu cherches grace à MATCH AGAINST

    MATCH('caracteristiques') AGAINST("champrecherche:valeurrecherche;") ;

    Ou alors avec un bon vieuw like, mais là c'est plus lourd.
    Ca te donne l'avantage de gérer un nombre de caractéristiques qui varie énormément, et d'introduire tout naturellement de nouvelles caractéristiques.

    Par contre c'est peu académique.
     
  4. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    Houlà les mecs... vous êtes super-rapides, mais je suis super-nul en fait...

    Ce que je cherche c'est à arriver à définir si la colonne sera vide ou pas, et à savoir si je l'affiche, ou non ;)
     
  5. Bourriquet
    Bourriquet WRInaute impliqué
    Inscrit:
    19 Septembre 2005
    Messages:
    561
    J'aime reçus:
    0
    Bah dans ce cas, après ton select, et ton fetch_array

    Tu testes chacun des champs retournés et tu vérifie si il est nul ou pas

    Code:
    
    $reccord_set = mysql_query( ici ta requête ) ;
    while ($reccord_set && $reccord = mysql_fetch_array($reccord_set)) {
    
      foreach($reccord as $champ) {
        if (!empty($champ)) echo key($reccord).":".$champ ;
      }
    
    
    }
    
    
    Par exemple...
     
  6. Sir Dipp
    Sir Dipp WRInaute impliqué
    Inscrit:
    21 Juillet 2003
    Messages:
    899
    J'aime reçus:
    0
    Il y a pas quelque chose en MySQL du genre NOT NULL ? Il me semble que tu peux éviter d'afficher certains champs en faisant ça ?

    Faut voir dans la documentation avec IF NULL.

    A+
     
  7. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    C'est justement mon stress, je peux écater les cellules vides d'une "ligne", mais je voudrais écarter la "colonne" dans le cas unique ou toutes les cellules de cette même colonne sont vides...

    Tu vois le binz ?
     
  8. Sir Dipp
    Sir Dipp WRInaute impliqué
    Inscrit:
    21 Juillet 2003
    Messages:
    899
    J'aime reçus:
    0
    Si MySQL le permet, tu pourrais faire une vue, mais cela risque d'être un peu lourd. Le mieux est d'effectivement passer par PHP ou tout autre language dynamique.
     
  9. blman
    blman WRInaute accro
    Inscrit:
    5 Septembre 2003
    Messages:
    2 719
    J'aime reçus:
    3
    Houlalala, HawkEye_TpfH, ta structre de table n'est pas du tout optimisée. Que ce passera-t-il le jour où il faudra ajouter une option à un produit que tu n'avait pas prévu ?

    Moi je ferais :
    - une table produit (reference, ..., id_produit)
    - une table option (designation, ..., id_option)
    - une table option_produit (id_produit, id_option, valeur)

    Cette structure te permet de rajouter soit plusieurs option à un produit soit aucune.
     
  10. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    Wow...

    Serais-je encore plus c* que je ne le pensais ?

    Vu l'heure, je vais étudier ta proposition demain matin, juste après le café ;)

    Merci en tout cas.
     
  11. Sir Dipp
    Sir Dipp WRInaute impliqué
    Inscrit:
    21 Juillet 2003
    Messages:
    899
    J'aime reçus:
    0
    J'acquisse et rejoint blman pour effectivement dire que c'est beaucoup plus simple !

    * encore un message pour rien dire...*
     
  12. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    okido, blman est-ce que tu peux développer un poil?

    Je te mets ci-dessous ce qu'était mon idée originale, histoire d'être sûr qu'on parle de la même chose ;)

    [​IMG]
     
  13. blman
    blman WRInaute accro
    Inscrit:
    5 Septembre 2003
    Messages:
    2 719
    J'aime reçus:
    3
    OK !


    table ARTICLE :
    ------------------------
    item_id
    into_product
    part_num
    ------------------------

    table OPTION
    ----------------------
    libelle
    id_option
    ----------------------
    Exemple de libéllé : volt, watt, L, l, h, ...


    table OPTION_PRODUIT
    -------------------------
    item_id
    id_option
    valeur
    -------------------------

    ATTENTION, je ne connais pas ton projet, peut-être que cette structure de table ne correspond pas du tout à tes besoins. Mais en tout cas, tu n'a pas d'enregistrement vide (donc plus optimisé) et elle est plus évolutive (si par exemple, tu dois rajouter d'autres options).

    C'est le genre de structure qu'on pourrait utiliser sur un site de vente de T-shirt par exemple avec les tailles (XL, XXL, L, ...) et les coloris...
     
  14. spidetra
    spidetra WRInaute passionné
    Inscrit:
    7 Juillet 2003
    Messages:
    1 215
    J'aime reçus:
    0
    +1 pour blman.
    HawkEye_TpfH surtout ne t'embarque pas dans une structure de table en colonne !
    C'est un cas classique de gestion des attributs produits dans un SGBDR.
    Inspire-toi de la structure de blman.
    Tu doit traiter tes attributs de manière générique et dynamique ( des lignes dans une table de ton SGBDR ), et non pas de manière statique ( des colonnes dans une table ).
    Tu pourra trouver des exemples dans des solutions comme osCommerce.
    Voilà par exemple la structure de la table products_attributes.

    Code:
    -- phpMyAdmin SQL Dump
    -- version 2.6.1-pl3
    -- http://www.phpmyadmin.net
    -- 
    -- Serveur: localhost
    -- Généré le : Jeudi 09 Février 2006 à 10:46
    -- Version du serveur: 4.1.10
    -- Version de PHP: 5.0.4
    -- 
    -- Base de données: `oscommerce`
    -- 
    
    -- --------------------------------------------------------
    
    -- 
    -- Structure de la table `products_attributes`
    -- 
    
    CREATE TABLE `products_attributes` (
      `products_attributes_id` int(11) NOT NULL auto_increment,
      `products_id` int(11) NOT NULL default '0',
      `options_id` int(11) NOT NULL default '0',
      `options_values_id` int(11) NOT NULL default '0',
      `options_values_price` decimal(15,4) NOT NULL default '0.0000',
      `price_prefix` char(1) NOT NULL default '',
      `products_options_sort_order` int(6) NOT NULL default '0',
      `product_attributes_one_time` tinyint(1) NOT NULL default '0',
      `products_attributes_weight` decimal(5,2) NOT NULL default '0.00',
      `products_attributes_weight_prefix` char(1) NOT NULL default '',
      `products_attributes_units` int(4) NOT NULL default '0',
      `products_attributes_units_price` decimal(15,4) NOT NULL default '0.0000',
      PRIMARY KEY  (`products_attributes_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    
     
  15. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    'faut que je comprenne là...

    laissez moi quelques minutes ;)
     
  16. blman
    blman WRInaute accro
    Inscrit:
    5 Septembre 2003
    Messages:
    2 719
    J'aime reçus:
    3
    Alors HawkEye_TpfH, tu t'en sort ?
     
  17. HawkEye
    HawkEye WRInaute accro
    Inscrit:
    23 Février 2004
    Messages:
    13 857
    J'aime reçus:
    5
    pas tellement, d'autant que la "table unique" est quasiment incontournable :(

    Mais je contourne le problème... ;)
     
  18. spidetra
    spidetra WRInaute passionné
    Inscrit:
    7 Juillet 2003
    Messages:
    1 215
    J'aime reçus:
    0
    Pourquoi ? Pourquoi es-tu obligé d'avoir une table unique ?
    Tu peux nous en dire plus.

    Je ne sais pas quelles sont tes contraintes, mais à terme, si ton système évolue trop, la structure en colonne est une impasse.
    Réfléchis bien avant d'adopter une telle structure.