Filtrer et grouper un array json et faire des calculs php
LearnDeep
Messages postés
67
Date d'inscription
Statut
Membre
Dernière intervention
-
jordane45 Messages postés 38486 Date d'inscription Statut Modérateur Dernière intervention -
jordane45 Messages postés 38486 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour , je suis nouveau dans le monde de php OO , j'ai crée une application php qui a la base de données suivante:

Aprés obtenu on json array , le résultat n'était pas comme je cherche :
Voici un petit morceau pour expliquer mon problème pour les produits qui ont la ligne Salami et le produit Mazraa le résultat correct doit etre comme ça comme dans la base de données
On peut voir que dans ce json il ya des problèmes:
1/ des produits ont la meme ligne et produit mais sont séparés dans des lignes json séparées.
2/ pour le calcul de quantité chaque produit qui est a une heure ou date différente est dans une ligne json séparée.
Ce que je cherche
le calcul de quantité pour chaque mois dans le json doit etre la somme des qte (somme de chaque mois séparés)pour chaque produits identiques dans la ligne et le produit
- il n'est pas important quand on va grouper les produit qui ont la meme ligne et produits de remplacer quelques données comme la date et heure puisque les porduits identiques(ligne,produit) peuvent prendre les données du premier produit du groupes des produits identiques.
- seulement la partie mois qui va changer de calcul puisque pour chaque groupe de produit identique:
pour le mois 1 = qte(prod1 dans le mois 1) + qte(prod2 dans le mois 2) + ......
....
pour le mois 12 = qte(prod1 dans le mois 12) + qte(prod2 dans le mois 12) + ......
Explication avec json:
Le résultat doit avoir la meme structure du json suivant puique le but et seulement de grouper et corriger les calquls des qte dans chaque mois:
On peut voir que le groupement a été bien passé et le json a gardé la meme structure mais le plus important est que les calculs de qte pour chaque mois est correcte maintenant puisque dans la bd il ya deux produits Mazraa ont une qte pour le mois 8 100,220 = 100+ 220 = 320
et ont un seul produit Mazraa qui aussi une qte mais dans le mois 10 alors 250 = 250
tous ça est montré dans le json.
Je suis entrain de chercher une solution pour obtenir le json que je cherche depuis une semaine mais c'est trop complexe.
Voici la partie PHP:
le but majeur est de corriger les calculs et de grouper avec conserver la structure génerale du array json comme j'ai montré dans le json cible que je voudrais obtenir.
J'éspere que je vais trouver une solution puisque je suis entrain de chercher plus d'une semaine.
Aprés obtenu on json array , le résultat n'était pas comme je cherche :
[ { "ligne": "Biscuit", "products": [ { "id": "8", "ligne": "Biscuit", "produit": "Major", "date": "2021-08-11", "heure": "10:00", "qte": "130", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 130 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "9", "ligne": "Biscuit", "produit": "Saida", "date": "2021-08-11", "heure": "11:00", "qte": "250", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 250 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] }, { "ligne": "Eau", "products": [ { "id": "6", "ligne": "Eau", "produit": "Safia 1.5", "date": "2021-08-11", "heure": "14:00", "qte": "200", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 200 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "7", "ligne": "Eau", "produit": "Marwa 2", "date": "2021-08-11", "heure": "9:00", "qte": "120", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 120 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] }, { "ligne": "Lait", "products": [ { "id": "12", "ligne": "Lait", "produit": "Vitalait 1/2", "date": "2021-08-11", "heure": "8:00", "qte": "80", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 80 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "13", "ligne": "Lait", "produit": "Vitalait 1/2", "date": "2021-08-11", "heure": "13:00", "qte": "99", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 99 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "16", "ligne": "Lait", "produit": "Delice", "date": "2021-06-11", "heure": "9:00", "qte": "200", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 200 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 0 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] }, { "ligne": "Salami", "products": [ { "id": "10", "ligne": "Salami", "produit": "Mazraa", "date": "2021-08-11", "heure": "8:00", "qte": "100", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 100 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "11", "ligne": "Salami", "produit": "Mazraa", "date": "2021-08-11", "heure": "13:00", "qte": "220", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 220 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "17", "ligne": "Salami", "produit": "Mazraa", "date": "2021-10-12", "heure": "11:00", "qte": "250", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 0 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 250 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] }, { "ligne": "Yaourt", "products": [ { "id": "4", "ligne": "Yaourt", "produit": "Delice", "date": "2021-08-11", "heure": "12:00", "qte": "150", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 150 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "5", "ligne": "Yaourt", "produit": "Delice", "date": "2021-08-11", "heure": "11:00", "qte": "90", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 90 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "14", "ligne": "Yaourt", "produit": "Delice ", "date": "2021-07-11", "heure": "10:00", "qte": "80", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 80 }, { "month": 8, "qte": 0 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "15", "ligne": "Yaourt", "produit": "Delice ", "date": "2021-08-11", "heure": "14:00", "qte": "200", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 200 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "18", "ligne": "Yaourt", "produit": "Delice", "date": "2021-04-1", "heure": "10:00", "qte": "500", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 500 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 0 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] } ]
Voici un petit morceau pour expliquer mon problème pour les produits qui ont la ligne Salami et le produit Mazraa le résultat correct doit etre comme ça comme dans la base de données
[ { "ligne": "Salami", "products": [ { "id": "10", "ligne": "Salami", "produit": "Mazraa", "date": "2021-08-11", "heure": "8:00", "qte": "100", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 100 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "11", "ligne": "Salami", "produit": "Mazraa", "date": "2021-08-11", "heure": "13:00", "qte": "220", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 220 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 0 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" }, { "id": "17", "ligne": "Salami", "produit": "Mazraa", "date": "2021-10-12", "heure": "11:00", "qte": "250", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 0 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 250 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] }, ] } ]
On peut voir que dans ce json il ya des problèmes:
1/ des produits ont la meme ligne et produit mais sont séparés dans des lignes json séparées.
2/ pour le calcul de quantité chaque produit qui est a une heure ou date différente est dans une ligne json séparée.
Ce que je cherche
le calcul de quantité pour chaque mois dans le json doit etre la somme des qte (somme de chaque mois séparés)pour chaque produits identiques dans la ligne et le produit
- il n'est pas important quand on va grouper les produit qui ont la meme ligne et produits de remplacer quelques données comme la date et heure puisque les porduits identiques(ligne,produit) peuvent prendre les données du premier produit du groupes des produits identiques.
- seulement la partie mois qui va changer de calcul puisque pour chaque groupe de produit identique:
pour le mois 1 = qte(prod1 dans le mois 1) + qte(prod2 dans le mois 2) + ......
....
pour le mois 12 = qte(prod1 dans le mois 12) + qte(prod2 dans le mois 12) + ......
Explication avec json:
Le résultat doit avoir la meme structure du json suivant puique le but et seulement de grouper et corriger les calquls des qte dans chaque mois:
[ { "ligne": "Salami", "products": [ { "id": "10", "ligne": "Salami", "produit": "Mazraa", "date": "2021-08-11", "heure": "8:00", "qte": "100", "months": [ { "month": 1, "qte": 0 }, { "month": 2, "qte": 0 }, { "month": 3, "qte": 0 }, { "month": 4, "qte": 0 }, { "month": 5, "qte": 0 }, { "month": 6, "qte": 0 }, { "month": 7, "qte": 0 }, { "month": 8, "qte": 320 }, { "month": 9, "qte": 0 }, { "month": 10, "qte": 250 }, { "month": 11, "qte": 0 }, { "month": 12, "qte": 0 } ], "year": "2021" } ] } ]
On peut voir que le groupement a été bien passé et le json a gardé la meme structure mais le plus important est que les calculs de qte pour chaque mois est correcte maintenant puisque dans la bd il ya deux produits Mazraa ont une qte pour le mois 8 100,220 = 100+ 220 = 320
et ont un seul produit Mazraa qui aussi une qte mais dans le mois 10 alors 250 = 250
tous ça est montré dans le json.
Je suis entrain de chercher une solution pour obtenir le json que je cherche depuis une semaine mais c'est trop complexe.
Voici la partie PHP:
public function getProductsStatsByMonths(){ $today = date("Y-m-d"); $date_arr = explode("-", $today); $year = $date_arr[0]; $month = $date_arr[1]; $day = $date_arr[2]; $prods = array(); $months = array( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ); $lignes = array(); $products = array(); $prodmonths = array(); $final = array(); $st = $this->conn->prepare("SELECT ligne from production group by ligne"); $st->execute(); while($row = $st->fetch(pdo::FETCH_ASSOC)){ array_push($lignes,$row["ligne"]); } foreach ($lignes as $ln){ $stmt = $this->conn->prepare("SELECT qte as total , id ,ligne, produit, date, heure FROM production where YEAR(date) = ? and ligne= ? "); $stmt->execute([$year,$ln]); $products = []; while($row = $stmt->fetch(pdo::FETCH_ASSOC)){ $p = new ProductsByCategory($row["id"],$row["ligne"],$row["produit"],$row["date"],$row["heure"],$row["total"],-1,$year); $date_arrrow = explode("-", $row["date"]); $rowmonth = $date_arrrow[1]; $prodmonths = []; foreach ($months as $month){ if(($rowmonth == $month) ){ array_push($prodmonths,new Months($month,(int) $row["total"])); }else if ($rowmonth != $month){ array_push($prodmonths,new Months($month,0)); } } $p->months = $prodmonths; array_push($products,$p); } $a = new ProductionByMonth($ln,$products); array_push($final,$a); } echo json_encode($final); }
le but majeur est de corriger les calculs et de grouper avec conserver la structure génerale du array json comme j'ai montré dans le json cible que je voudrais obtenir.
J'éspere que je vais trouver une solution puisque je suis entrain de chercher plus d'une semaine.
A voir également:
- Filtrer et grouper un array json et faire des calculs php
- Comment créer un groupe whatsapp - Guide
- Easy php - Télécharger - Divers Web & Internet
- Barbara veut calculer automatiquement son budget dans un tableau. citez un des logiciels lui permettant de faire des calculs sur des tableaux de nombres (tableur). - Forum Musique / Radio / Clip
- Citez un des logiciels lui permettant de faire des calculs sur des tableaux de nombres (tableur). ✓ - Forum LibreOffice / OpenOffice
- Budget plus cic ✓ - Forum finances
1 réponse
Bonjour,
Comment penses tu que nous puissions te répondre ... vu comment est écrite ta question et vu les code alambiqué que tu nous montres....
Sans parler du fait que nous ne savons rien de la structure de ta bdd ni de ce qu'elle contient
On ne sait pas non plus ce que font tes class ProductsByCategory .. ProductionByMonth ...
En plus, pourquoi faire des trucs du genre
Alors qu'un fetchAll fait déjà ça ..
Et enfin.. faire des requêtes dans une boucle .. aie.. mauvaise pratique ...
Je pense que tu pourrais obtenir le résultat souhaité en faisant déjà la bonne requête...
Il ne resterait plus qu'à traiter l'array obtenu pour le remettre en forme comme tu le désires.
Déjà, que donne la requête ( à faire directement dans ta bdd via phpmyadmin par exemple.. )
Avec une requête de ce genre, tu devrais approcher du résultat souhaites ( faudra peut-être jouer sur le GROUP BY (en inversant l'ordre des champs ))
Comment penses tu que nous puissions te répondre ... vu comment est écrite ta question et vu les code alambiqué que tu nous montres....
Sans parler du fait que nous ne savons rien de la structure de ta bdd ni de ce qu'elle contient
On ne sait pas non plus ce que font tes class ProductsByCategory .. ProductionByMonth ...
En plus, pourquoi faire des trucs du genre
while($row = $st->fetch(pdo::FETCH_ASSOC)){ array_push($lignes,$row["ligne"]); }
Alors qu'un fetchAll fait déjà ça ..
Et enfin.. faire des requêtes dans une boucle .. aie.. mauvaise pratique ...
Je pense que tu pourrais obtenir le résultat souhaité en faisant déjà la bonne requête...
Il ne resterait plus qu'à traiter l'array obtenu pour le remettre en forme comme tu le désires.
Déjà, que donne la requête ( à faire directement dans ta bdd via phpmyadmin par exemple.. )
SELECT YEAR(date) as Annee , MONTH(date) as Mois , DATE_FORMAT(date,'Ym') as YM , SUM(qte) as total , , ligne , produit ,date , heure FROM production GROUP BY DATE_FORMAT(date,'Ym'), line, produit
Avec une requête de ce genre, tu devrais approcher du résultat souhaites ( faudra peut-être jouer sur le GROUP BY (en inversant l'ordre des champs ))
https://forums.commentcamarche.net/forum/affich-37310301-extraire-les-produits-qui-n-ont-pas-une-qte-dans-un-mois-donnee#1
??
merci pour votre réponse
la structure de la bd:
le problème dans fetchAll() est qu'elle va etre plus difficile a traiter parceque il y'a beaucoup de array_push etc ..
pour la classe ProductsBYCategory:
Pour la classe getProductsSTatsBYMonths:
pour la classe ProductsBYCategory:
J'ai essayé avec group by mais cela va écraser les qte lors de la requete quand il y'a des produits qui ont le meme ligne et produit mais dans une date ou heure différente , c'est pourquoi je préfere le traitement de groupement par array, et grouper tous les données identiques dans les deux champs(ligne,produit) pour calculer correctement les qte mois par mois
J'ai tout essayé pour une semaine mais vraiment j'ai échoué.
Tu as regardé la requête que je t'ai envoyé ??
Tu as vu que dans le group by j'y ai mis plusieurs champs ???
L'as tu , au moins, testé ???