dispatcher un résultat sql selon le mois..

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : dispatcher un résultat sql selon le mois..

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

par sadeq » 15 mars 2011, 22:41

Modération :
Si ta question est résolue, pense à l'indiquer pour que les futures personnes qui voudront consulter ce sujet sachent qu'il contient une solution.
Tu peux réaliser cette opération toi-même en cliquant sur le bouton Image en haut à droite de la réponse qui te semble la plus pertinente.

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

par pamalalarache » 15 mars 2011, 13:08

en fait nan c bon ^^
cette page est opérationel
je peux enfin passer à autre chose
je devenais fou

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

par pamalalarache » 15 mars 2011, 11:52

juste un petit détail, si il n'y a pas de quantité pour un mois donné, je n'arrive pas à créer une case de tableau avec 0 dedans.
J'ai essayé avec les isset et les choses comme ca

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

par pamalalarache » 15 mars 2011, 11:03

et ben franchement je te remercie énormément. Ca fonctionne nickel. Merci pour le temps passé sur mon problème.
Vous êtes vraiment efficace.
Merci, bonne continuation

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

par xTG » 14 mars 2011, 18:59

Il est désormais plus que clair que prendre du recul n'est pas une perte de temps. :P

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

par sadeq » 14 mars 2011, 18:34

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à.

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

par pamalalarache » 14 mars 2011, 17:57

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..

par pamalalarache » 14 mars 2011, 17:36

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..

par xTG » 14 mars 2011, 17:15

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..

par pamalalarache » 14 mars 2011, 14:06

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..

par xTG » 14 mars 2011, 13:59

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..

par pamalalarache » 14 mars 2011, 11:02

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..

par xTG » 11 mars 2011, 19:36

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..

par Invité » 11 mars 2011, 16:49

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..

par xTG » 11 mars 2011, 16:42

Mon code est basé sur ce que t'a proposé Mazarini et non sur ta dernière requête. ;)