Page 1 sur 2

dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 12:49
par zion75
Bien le bonjour, j'ai un petit soucis, à mon avis c plus un problème de logique..
Je vous explique:

Je veux afficher les la quantité total de produits et ensuite dans un tableau html, dispatcher cette quantité selon les mois.

Exemple:
produit || quantité || janvier || février || mars ect ....
produit x || 6 || 4 || 2 || 0 et que des 0 pour les autres moi

quantité total= 6 dont 4 en janvier et 2 en février

Moi pour le moment ca m'affiche qtté total = 6 mais en janvier = 6 et les autres mois 0 .. Ca me dispatche pas la qtité de produit selon les mois..

Mon code:
 $sql = "SELECT	date_commande,
			CONCAT(produits.nom, ' ', produits.poids, ' ', produits.parfum) AS article,
			SUM(quantite - cadeau) AS quantite,
			SUM(cadeau) AS cadeau,
			 MONTH( date_commande ) AS date,
			commandes_detail.id_produit
	    FROM	commandes_detail
	    LEFT JOIN	commandes ON commandes_detail.id_commande = commandes.id
	    LEFT JOIN	produits ON commandes_detail.id_produit = produits.id
	    WHERE statut = 100
	    GROUP BY	id_produit
	    ORDER BY	article";
    sql_mysql_query($sql);]
et coté php :

Code : Tout sélectionner

[html] <td align="right"><?php if ($row->date==1) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==2) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==3) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==4) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==5) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==6) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==7) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==8) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==9) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==10) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==11) echo $row->quantite; ?> </td> <td align="right"><?php if ($row->date==12) echo $row->quantite; ?> </td>[/html] date==1 >> janvier ect... Comment dois je faire pour résoudre mon problème et que la quantité soit réparti correctement selon le mois ???

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 15:01
par Mazarini
Bonjour

GROUP BY id_produit,MONTH( date_commande )

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 15:19
par Invité
bjr, déjà tenté ca.

Le problème c que dans phpmyadmin par exemple, ca ressort sous cette forme là :

produit X quantité 4 mois 1
produit X quantité 2 mois 2

Donc en sortie à l affichage, je n'arriverais pas à faire un truc du style :

produit // quantité // janvier // février
produit X // 6 // 4 //2

En faisant ce group by ca me donne :
produit // quantité // janvier // février
produit X // 4 // 4 // 0
produit X // 2 // 0 // 2

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 15:37
par xTG
Mazarini a raison, ton traitement est bien plus simple à traiter au niveau de l'affichage que dans la requête.

Il ne faut pas confondre requête et affichage, la requête ne représente pas forcement l'affichage final.

En PHP tu peux utiliser une variable tampon afin de savoir si tu changes de produit.
Ainsi :
$tmp = "";
foreach(.... as $prod)
{
  if( $prod->nom != $tmp )
    echo "</tr><tr>";
  $tmp = $prod->nom;
  echo "<td>{$prod->quantite}</td>";
}
Ecrit à la va vite car un contre-temps et je dois m'en aller. :(

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 16:26
par zion75
Je ne vois pas comment faire pour fusionner ces deux lignes.

Ce que j'obtiens avec la requête modifiés.

produit // quantité // janvier // février
produit X // 4 // 4 // 0
produit X // 2 // 0 // 2
produit Y // 5 // 5 // 0

Voilà, maintenant je voudrais regrouper les produits qui ont le même nom ensemble
Donc additionner la quantité totale mais garder les quantités respectives pour janvier et février.


produit // quantité // janvier // février
produit X // 6 // 4 // 2

Le problème que je rencontre c'est que ma variable pour quantité totale et quantité pour un mois est la même $row->quantite.

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 16:42
par xTG
Mon code est basé sur ce que t'a proposé Mazarini et non sur ta dernière requête. ;)

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 16:49
par Invité
behh justement, j'ai modifié ma requête avec ce qu' a dit mazarini, et j'arrive au résultat que je poste dans le message précédent. Il faut donc que maintenant niveau affichage je fusionne les deux lignes avec le même produit

prod /qtité total / janv / fevr
C-1100 100 gelules /2 /2/0
C-1100 100 gelules /4/0/4

Désolé si je suis un peu lourd a comprendre :p Mais je ne vois pas du tout comment adapter ton code à ce que je veux faire.

Re: dispatcher un résultat sql selon le mois..

Posté : 11 mars 2011, 19:36
par xTG
Je persiste dans ce que j'ai dit.
Si tu as bien la requête de départ avec les modifications sur le group_by tu ne dois avoir qu'un seul mois dans un n-uplet. ^^

Sinon pour mon code il n'y a pas plus simple en fait. :/
Le but est de stocker le nom du produit dans une variable afin de la comparer au prochain n-uplet et savoir si c'est toujours le même (on fait un nouveau <td>) ou bien un nouveau produit (on ferme le <tr> et on en ouvre un autre).

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 11:02
par pamalalarache
bonjour c'est moi, je me suis inscrit sur le forum donc jai changé de nom.
J'aurai encore besoin de ton aide. Après avoir bien réfléchi j'ai pondu ca :
 while ($row = mysql_fetch_object($query)) {
	
	$tab[$row->article][$row->date] = $row->quantite;	$c^=1;
	$class_fond = "ligne$c";
	if ($row->article == $tmp) {
			$qtite_tmp += $row->quantite;
			 echo "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
			}
			
			else { ?>
    <tr class="ligne <?php echo $class_fond; ?>" onMouseOver="this.className='ligne ligne_survol'" onMouseOut="this.className='ligne <?php echo $class_fond; ?>'">
	<td><?php if ($rech_commandes_site != 9999 && isset($row->id_produit) && $row->id_produit != 999999) { ?><a href="../../catalogue/produits/modif.php?id=<?php echo $row->id_produit ?>" title="Afficher la fiche produit"><?php } echo (isset($row->id_produit) && $row->id_produit == 999999) ? 'Carte de fidélité' : tohtml($row->article); if ($rech_commandes_site != 9999 && isset($row->id_produit) && $row->id_produit != 999999) { ?></a><?php } ?></td>
	<td align="right"><?php if ($row->quantite) echo $row->quantite ?></td>
	<td align="right"><?php if ($rech_commandes_site != 9999 && $row->cadeau) echo $row->cadeau ?></td>
	<?php

	

		
			 $tmp = $row->article;
			for ($row->date = 1; $row->date < 13; $row->date++) {
			$row->quantite = $qtite_tmp;
     echo '<td>';
     echo isset ($tab[$row->article][$row->date]) ? $tab[$row->article][$row->date] :0;
     echo '</td>';
}
}
Ca me sort bien qu'une ligne : C-1100 100 gelules 2 2
Mais toujours pas comme il faut ; C-1100 100 gelules 6 2 4


Je perds tout mon temps là dessus. Une idée pour m'aider?

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 13:59
par xTG
Encore et toujours la même chose...
Pourquoi tu récupères plusieurs mois dans un seul n-uplet ?

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 14:06
par pamalalarache
ben ma requete dans la BDD sous phpmyadmin me retourne un seul mois par n uplet
date_commande /article /quantite / cadeau /date /id_produit
011-01-31 15:47:34 /C-1100 100 gelules / 2/ 0 / 1/ 4208
2011-02-02 13:05:19 /C-1100 100 gelules/ 4 / 0/ 2 / 4208

chaque n uplet a un seul mois donc comme dans l exemple ci dessus le produit peut apparaitre en double

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 17:15
par xTG
Au temps pour moi ! Je croyais que tes colonnes actuelles quantite et cadeau faisaient références aux colonnes janvier et février que tu indiquaient plus haut !
Je suis au boulot pour le moment, mais je me penche sur ton soucis ce soir. :)

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 17:36
par pamalalarache
cool ^^
merci de ton aide

Je fais plein de version parrallèles en même temps. Celle ci me donne presque ce qu'il me faut.
  while ($row = mysql_fetch_object($query)) {
	
	$tab[$row->article][$row->date] = $row->quantite;	$c^=1;
	$class_fond = "ligne$c";
	$tab_test[$row->date] = $row->quantite;
	
	if ($row->article == $tmp) {
	
			$qtite_tmp += $row->quantite;
			$mois += $tab[$row->article][$row->date];
			echo 'iiiiiiiii';
			
			}
			
			else { 
			
			$qtite_tmp = $row->quantite;
			$mois = $tab[$row->article][$row->date] ;
			$tmp = $row->article;
			
			}
		
			
		?>
    <tr class="ligne <?php echo $class_fond; ?>" onMouseOver="this.className='ligne ligne_survol'" onMouseOut="this.className='ligne <?php echo $class_fond; ?>'">
	<td><?php if ($rech_commandes_site != 9999 && isset($row->id_produit) && $row->id_produit != 999999) { ?><a href="../../catalogue/produits/modif.php?id=<?php echo $row->id_produit ?>" title="Afficher la fiche produit"><?php } echo (isset($row->id_produit) && $row->id_produit == 999999) ? 'Carte de fidélité' : tohtml($row->article); if ($rech_commandes_site != 9999 && isset($row->id_produit) && $row->id_produit != 999999) { ?></a><?php } ?></td>
	<td align="right"><?php if ($row->quantite) echo $qtite_tmp ?></td>
	<td align="right"><?php if ($rech_commandes_site != 9999 && $row->cadeau) echo $row->cadeau ?></td>

<?php
$tmp = $row->article;
foreach ($tab as $produit=>$quantites) {
for ($mois = 1; $mois < 13; $mois++) {
     echo '<td>';
     echo isset($quantites[$mois]) ? $quantites[$mois] : 0;
     echo '</td>';
}
}

En faisant ce code, je me retrouve en sortie ( en affichage php) à quelque chose comme ca :

Code : Tout sélectionner

nom du prod qtité total / janvier/février C-1100 100 gelules 2 2 0 C-1100 100 gelules 6 2 4
Donc la deuxième ligne me donne exactement ce que je veux, mais du coup il faudrait trouver un moyen que la première ligne ne s'affiche pas du tout !!!
Je suis plus très loin mais c'est pas encore ca ...

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 17:57
par pamalalarache
oué en fait niveau affichage quand il y a plein de produit ca fait n'importe quoi..

Pour le premier produit il y a bien 12 chiffre correspondant aux quantité de chaque mois.
Pour le deuxieme produit, il y en a 24 puis apres 36 ect...
Il doit y avoir un prbleme de boucle pourtant je le vois pas :d

Re: dispatcher un résultat sql selon le mois..

Posté : 14 mars 2011, 18:34
par sadeq
Bonjour,

Permettez-moi de mettre ma plume dans ce sujet en proposant une solution.

Partant de la requête SQL de départ postée au début du sujet, je préconise de regrouper le résultat attendu par produit et par mois. Comme ça on aura pour chaque produit les quantités mensuelles. La somme des quantités mensuelles peut être obtenu par PHP dans le traitement de l'affichage.
 //Requête SQL: regroupement par produit et par mois
$sql = "SELECT  commandes_detail.id_produit,  MONTH( date_commande ) AS mois,
                        CONCAT(produits.nom, ' ', produits.poids, ' ', produits.parfum) AS article,
                        SUM(quantite - cadeau) AS quantite_mois,
                        SUM(cadeau) AS cadeau_mois

            FROM        commandes_detail
            LEFT JOIN   commandes ON commandes_detail.id_commande = commandes.id
            LEFT JOIN   produits ON commandes_detail.id_produit = produits.id
            WHERE statut = 100
            GROUP BY    id_produit, MONTH(date_commande)
            ORDER BY     id_produit, MONTH(date_commande)";
On peut consolider le résultat de cette requête SQL par PHP pour obtenir l'organisation adéquate exigée par l'affichage.
Voici donc la structure de cette organisation:
produit || quantité || janvier || février || mars ect ....
produit x || 6 || 4 || 2 || 0 et que des 0 pour les autres mois
On a besoin pour ça d'un tableau qui regroupe les données en amont par produit et en aval par mois comme ça:
$données["produit x"] : Le Niveau 1 du tableau est bien sûr le niveau produit
$données["produit x"]["quantité_totale"] : Le Niveau 2 du tableau comprend la quantité totale (somme des quantités des mois)
$données["produit x"]["mois"] : Le Niveau 2 comprend aussi un nœud nommé "mois" pour les quantités mensuelles de (janvier, février, ... etc.)
$données["produit x"]["mois"]["janvier"] : et donc les quantités sont stockées au niveau 3 (niveau de chaque mois)
$données["produit x"]["mois"]["février"]
$données["produit x"]["mois"][... etc .]

La même structure se répètera pour les autres produits à partir du Niveau 1:
$données["produit y"]
$données["produit y"]["quantité_totale"]
$données["produit y"]["mois"]["janvier"]
$données["produit y"]["mois"]["février"]
$données["produit y"]["mois"][... etc .]

Donc, un produit n'apparaitra dans ce tableau qu'une seule fois comme un nœud contenant les infos produit et surtout un sous-tableau des quantités mensuelles.

Maintenant comment obtenir cette structure hiérarchique à partir du résultat de la requête SQL? la réponse est le programme suivant:
<?php
//Se connecter à la base de données
mysql_connect("localhost","root");
mysql_select_db("test");

//Requête SQL: regroupement par produit et par mois
$sql = "SELECT  commandes_detail.id_produit,  MONTH( date_commande ) AS mois,
                        CONCAT(produits.nom, ' ', produits.poids, ' ', produits.parfum) AS article,
                        SUM(quantite - cadeau) AS quantite_mois,
                        SUM(cadeau) AS cadeau_mois
            FROM        commandes_detail
            LEFT JOIN   commandes ON commandes_detail.id_commande = commandes.id
            LEFT JOIN   produits ON commandes_detail.id_produit = produits.id
            WHERE statut = 100
            GROUP BY    id_produit, MONTH(date_commande)
            ORDER BY     id_produit, MONTH(date_commande)";
			
//Exécution de la requête SQL
$resultat = mysql_query($sql);

//Tableau du résultat
$données = array();

//Création de la structure d'affichage dans le tableau $données
while ($resultat && $row = mysql_fetch_array($resultat))
{
    //extraire les données utiles aux index de niveaux du tableau : produit et mois
    $produit = $row["id_produit"];
    $mois = $row["mois"];

	//créer les noeuds produit du tableau s'ils n'existent pas, sinon ils seront mis à jour pour consolider les données par produit
	if (!isset($données[$produit]))
	{
		$données[$produit] = array();
		$données[$produit]["mois"] = array();
		$données[$produit]["quantité_totale"] = 0;
	}

    //mettre à jour les données (quantités et quantité totale)  du tableau $données
    $données[$produit]["mois"][$mois] = $row["quantite_mois"]; //niveau 3 du tableau : quantités mensuelles du produit

   //Cumuler les quantités du produit pour obtenir un total
    $données[$produit]["quantité_totale"] += $row["quantite_mois"]; //somme des quantités mensuelles du produit
}

//Affichage du tableau résultat
echo "<table border='1'><tr><th>Produit</th><th>Qté Totale</th><th>Janvier</th><th>Février</th><th>Mars</th><th> ... les autres mois ...</th></tr>";
foreach($données as $produit=>$ligne)  //niveau 1 du tableau
{
     //1 produit par ligne composée par 1 colonne par mois
     // on commence par le produit et la quantité totale dans les 2 premières colonnes
     echo "<tr><td>" . $produit . "</td><td>". $ligne["quantité_totale"] . "</td>";  // niveau 2 du tableau : produit et qté totale
     // en suite les quantités mensuelles dans les colonnes suivantes
     foreach($ligne["mois"] as $mois=>$quantité_mois)
     {
          echo "<td>". $quantité_mois . "</td>";  //niveau 3 du tableau : qté mensuelles
     }
    //fin de la ligne produit
    echo "</tr>";
}
//fin de l'affichage
echo "</table>";
 ?>
Voici ma base de données de test:
-- phpMyAdmin SQL Dump
-- version 3.3.9
-- http://www.phpmyadmin.net
--
-- Serveur: localhost
-- Généré le : Lun 14 Mars 2011 à 18:50
-- Version du serveur: 5.5.8
-- Version de PHP: 5.3.5

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Base de données: `test`
--

-- --------------------------------------------------------

--
-- Structure de la table `commandes`
--

CREATE TABLE IF NOT EXISTS `commandes` (
  `id` int(11) DEFAULT NULL,
  `date_commande` datetime DEFAULT NULL,
  `statut` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Contenu de la table `commandes`
--

INSERT INTO `commandes` (`id`, `date_commande`, `statut`) VALUES
(1, '2011-01-01 00:00:00', 100),
(2, '2011-02-01 00:00:00', 100),
(3, '2011-03-01 00:00:00', 100);

-- --------------------------------------------------------

--
-- Structure de la table `commandes_detail`
--

CREATE TABLE IF NOT EXISTS `commandes_detail` (
  `id_commande` int(11) DEFAULT NULL,
  `id_produit` int(11) DEFAULT NULL,
  `quantite` int(11) DEFAULT NULL,
  `cadeau` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Contenu de la table `commandes_detail`
--

INSERT INTO `commandes_detail` (`id_commande`, `id_produit`, `quantite`, `cadeau`) VALUES
(1, 1, 5, 0),
(1, 2, 10, 0),
(2, 2, 20, 0),
(3, 1, 15, 1),
(3, 2, 15, 1);

-- --------------------------------------------------------

--
-- Structure de la table `produits`
--

CREATE TABLE IF NOT EXISTS `produits` (
  `id` int(11) DEFAULT NULL,
  `nom` varchar(50) DEFAULT NULL,
  `poids` int(11) DEFAULT NULL,
  `parfum` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Contenu de la table `produits`
--

INSERT INTO `produits` (`id`, `nom`, `poids`, `parfum`) VALUES
(1, 'Produit 1', 1, '1'),
(2, 'Produit 2', 1, '1');
*
Et voici le résultat d'exécution de mon programme:
Produit___Qté Totale ___Janvier___Février___Mars___... les autres mois ...
1__________19 __________5________14
2__________44 __________10_______20 ____14
Voilà.