[phpMySQL] - Ecarter les colonnes vides

WRInaute accro
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:

table_articles.gif


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

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

Merci !!![/img]
 
WRInaute accro
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) {
 
WRInaute impliqué
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.
 
WRInaute accro
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 ;)
 
WRInaute impliqué
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...
 
WRInaute impliqué
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+
 
WRInaute accro
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 ?
 
WRInaute impliqué
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.
 
WRInaute accro
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.
 
WRInaute accro
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.
 
WRInaute impliqué
J'acquisse et rejoint blman pour effectivement dire que c'est beaucoup plus simple !

* encore un message pour rien dire...*
 
WRInaute accro
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 ;)

masquer-colonnes-vides.gif
 
WRInaute accro
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...
 
WRInaute passionné
+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;
 
WRInaute passionné
HawkEye_TpfH a dit:
pas tellement, d'autant que la "table unique" est quasiment incontournable :(

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.
 
Discussions similaires
Haut