Partage
  • Partager sur Facebook
  • Partager sur Twitter

Plusieurs champs COUNT, GROUP BY

Plusieurs champs COUNT, GROUP BY

Sujet résolu
    7 septembre 2020 à 13:41:31

    Bonjour

    J'essaie de regrouper deux colonnes dans ma base de données MySQL et d'afficher les décomptes respectivement (sous forme de colonnes séparées).Existe-t-il un moyen de faire cela avec Mysql?


    ma table affaires ressemble a ceci :


    Ce que je souhaite obtenir est:

    1/ le nombre de toutes les affaires dont la date de creation tombe en semaine S ===> flux entrant par semaine
    2/ le nombre de toutes les affaires dont la date de cloture tombe en semaine S  ===> flux sortant par semaine

    avec deux requêtes séparées j’arrive bien a obtenir ce que je veux : 


    flux entrant par semaine=

    SELECT weekofyear(date_creation) AS semaine ,count(date_creation) as flux_entrant ,
     FROM affaires GROUP BY  semaine .


    flux sortant par semaine=

    SELECT weekofyear(date_cloture) AS semaine ,count(date_cloture) as flux_sortant ,
     FROM affaires GROUP BY  semaine .

     SVP je souhaite savoir si c'est possible de faire uniquement une seule requete pour avoir les deux résultats en meme temps comme ceci :

    J'ai essayé ca mais sa marche uniquement pour le flux entrant :

    SELECT weekofyear(date_creation) AS semaine,
    count(date_creation) as flux_entrant ,
    count(date_cloture) as flux_sortant
    FROM affaires GROUP BY semaine



    -
    Edité par Massi.dev 7 septembre 2020 à 14:08:20

    • Partager sur Facebook
    • Partager sur Twitter

    banounemassine

      7 septembre 2020 à 14:02:32

      Salut,

      de tête je pensais qu'on ne pouvait pas faire de group by sur un alias, teste ça:

      SELECT weekofyear(date_creation) AS semaine,
      count(date_creation) as flux_entrant ,
      count(date_cloture) as flux_sortant
      FROM affaires GROUP BY weekofyear(date_creation)



      • Partager sur Facebook
      • Partager sur Twitter
        7 septembre 2020 à 14:16:42

        Bonjour christouphe,

        Tout d'abord merci  pour ta réponse .

        Non le problème ne vient pas de la , on peut bien faire un group by sur un alias .

        La requete donne bien  un résultat mais pas celui que je cherche , quand je fais GROUP BY weekofyear(date_creation) OU
        GROUP BY semaine

        moi je cherche a faire

        =>un groupement par semaine de création pour calculer le nombre d'affaire créer par semaine

        puis

        => un groupement par semaine de cloture pour calculer le nombre d'affaire cloturer par semaine

        • Partager sur Facebook
        • Partager sur Twitter

        banounemassine

          7 septembre 2020 à 14:26:33

          Alors fait 2 sous requêtes pour chaque groupe et un select global. Je ne pense pas que ce soit possible sur une seule requête.

          EDIT:

          à tester, je suis pas sûr:

          SELECT
              weekofyear(date_creation) AS semaine,
              (SELECT count(date_creation) as flux_entrant ,
               FROM affaires GROUP BY  semaine) AS flux_entrant,
          
              (SELECT count(date_cloture) as flux_sortant ,
               FROM affaires GROUP BY  semaine) AS flux_sortant
          FROM
              affaires
          GROUP BY
              semaine



          -
          Edité par christouphe 7 septembre 2020 à 14:30:02

          • Partager sur Facebook
          • Partager sur Twitter
            7 septembre 2020 à 14:40:36

            Malheureusement ca me donne ca comme résultat :

            • Partager sur Facebook
            • Partager sur Twitter

            banounemassine

              7 septembre 2020 à 15:02:46

              bon je laisse voir ceux qui sont plus fort en SQL.

              Par contre je vais demander à transférer côté SQL ;)

              • Partager sur Facebook
              • Partager sur Twitter
                7 septembre 2020 à 15:56:46

                Bonjour,

                Pas si simple puisque pour le même enregistrement la semaine entrant peut être différente de la semaine sortant ... Donc il faut multiplier les sous-requêtes :

                une pour sortir la liste de semaines possibles (attention à l'année aussi ...)

                une pour compter les entrants

                une pour compter les sortants

                Au final ça fait une requête alambiquée :

                SELECT
                	S.annee,
                	S.semaine,
                	COALESCE( FE.nombre, 0 ) AS flux_entrants,
                	COALESCE( FS.nombre, 0 ) AS flux_sortants
                FROM
                	(
                		-- Liste des semaines existantes
                		-- Sur flux entrants
                		SELECT DISTINCT
                			YEAR( date_creation ) AS annee,
                			WEEKOFYEAR( date_creation ) AS semaine
                		FROM affaires
                
                		UNION
                
                		-- Sur flux sortants
                		SELECT DISTINCT
                			YEAR( date_creation ) AS annee,
                			WEEKOFYEAR( date_creation ) AS semaine
                		FROM affaires
                	) AS S
                	
                		LEFT JOIN (
                				-- Compteur flux entrants
                				SELECT
                					YEAR( date_creation ) AS annee,
                					WEEKOFYEAR( date_creation ) AS semaine,
                					COUNT( * ) as nombre
                				FROM affaires
                				GROUP BY
                					YEAR( date_creation ),
                					WEEKOFYEAR( date_creation )
                			) AS FE
                			ON S.annee = FE.annee
                			AND S.semaine = FE.semaine
                
                		LEFT JOIN (
                				-- Compteur flux sortants
                				SELECT
                					YEAR( date_cloture ) AS annee,
                					WEEKOFYEAR( date_cloture ) AS semaine,
                					COUNT( * ) as nombre
                				FROM affaires
                				GROUP BY
                					YEAR( date_cloture ),
                					WEEKOFYEAR( date_cloture )
                			) AS FS
                			ON S.annee = FS.annee
                			AND S.semaine = FS.semaine

                Autant te dire qu'il vaut mieux faire tes deux requêtes séparément et à les traitées dans ton code pour les regrouper dans un tableau ... Mais si cela ne te pique pas les yeux alors banco :D

                Déplacement vers un forum plus approprié

                Le sujet est déplacé de la section PHP vers la section Base de données

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  7 septembre 2020 à 16:07:59

                  salut,

                  avec les Window Functions de Mysql 8.0 ou mariaDB ou PostgreSQL

                  SELECT
                         weekofyear(date_creation) AS semaine,weekofyear(date_cloture) AS semaine_cloture,
                        COUNT(date_creation) OVER( PARTITION BY  weekofyear(date_creation) ) AS flux_entrant,
                        COUNT(date_cloture) OVER( PARTITION BY weekofyear(date_cloture)  ) AS flux_sortant
                        FROM affaires;

                  Ou sur des anciennes versions MySQL(<8):

                  SELECT  weekofyear(date_creation) AS semaine,weekofyear(date_cloture) AS semaine_cloture,
                         COUNT(CASE WHEN  weekofyear(date_creation)  THEN 1 ELSE null END) flux_entrant,
                         COUNT(CASE WHEN weekofyear(date_cloture)  THEN 1 ELSE null END) flut_sortant
                    FROM affaires
                  
                   GROUP BY semaine,semaine_cloture




                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 septembre 2020 à 16:14:49

                    Bonjour, 

                    Je pense que le problème est que tu fait tous sur date_creation et tu ne tiens pas compte de date_cloture dans ton SELECT et du coup tu à des resultat pour date_creation au debut et rien pour date_cloture

                     weekofyear(date_creation)

                    Sans réfléchir tu peux tous simplement faire un Union entre les deux Requête pour en avoir une seul ? 

                    Sinon je pense qu'il y a également moyen de s'en sortir avec 1 seul Select, mais j'ai pas la réponse tout de suite

                    Peut être en rajoutant egalement dans ton select  ou un truc du genre : 

                    weekofyear(date_creation) AS semaine, weekofyear(date_cloture) AS semaine2 

                    puis un GROUPE BY sur semaine2 egalement ? 

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Site Internet : https://devst.go.yj.fr

                      7 septembre 2020 à 16:23:48

                      Tout d'abord je tiens a vous remercier pour toutes vos réponses .

                      alors dans un autre Forum on ma proposé cette solution qui marche parfaitement :D

                      SELECT  semaine
                          ,   SUM(flux_entrant)   AS flux_entrant
                          ,   SUM(flux_sortant)   AS flux_sortant
                      FROM    (   SELECT  WEEKOFYEAR(date_creation)   AS semaine
                                     ,    COUNT(date_creation)        AS flux_entrant
                                     ,    0                           AS  flux_sortant
                                  FROM    affaires
                                  GROUP BY semaine
                              UNION ALL
                                  SELECT  WEEKOFYEAR(date_cloture)    AS semaine
                                     ,    0                           AS flux_entrant
                                     ,    COUNT(date_cloture)         AS flux_sortant
                                  FROM     affaires
                                  GROUP BY semaine
                              )   AS tmp
                      GROUP BY semaine
                      ;
                      seul souci pour moi c'est que j'ai deux autres tables avec les quelles je veux faire de jointure simple comme cela
                      SELECT DISTINCT semaine, 
                      	SUM(flux_entrant) AS flux_entrant , 
                      	SUM(flux_sortant) AS flux_sortant 
                      FROM  regions ,clients,affaires( 
                              SELECT 
                                          WEEKOFYEAR(date_creation) AS semaine, 
                                          COUNT(date_creation) AS flux_entrant , 
                                          0 AS flux_sortant 
                              FROM affaires
                              GROUP BY semaine
                              UNION ALL
                              SELECT
                                        WEEKOFYEAR(date_cloture) AS semaine, 
                                        0 AS flux_entrant , 
                                       COUNT(date_cloture) AS flux_sortant 
                              FROM affaires
                              GROUP BY semaine) AS tmp 
                              WHERE 
                                       affaires.commune_mes=regions.code_commune 
                              and 
                                        clients_mes.num_client= affaires.num_mes 
                              GROUP BY semaine

                       mais malheureusement ca ne marche pas

                      je pense que c'est normal puisque je dois dabord faire une jointure entre la table tmp et affaires !!!!

                      est ce que qlq1 a une idée SVP :honte:

                      -
                      Edité par Massi.dev 7 septembre 2020 à 16:24:25

                      • Partager sur Facebook
                      • Partager sur Twitter

                      banounemassine

                        7 septembre 2020 à 16:32:22

                        MassineBanoune a écrit:

                        cette solution qui marche parfaitement

                        Très astucieux l'utilisation de l'UNION, mais attention à la gestion de l'année ... Ici tout va bien parce que tu n'a qu'une année, mais dès que tu vas avoir des données à cheval sur plusieurs années ... pfiout ...

                        MassineBanoune a écrit:

                        malheureusement ca ne marche pas

                        Cela ne veut pas dire grand chose ... Mais rapidement comme ça il manque une virgule après le nom de table affaires à la ligne 4 ... et il va surtout manquer les conditions de jointure ...

                        Dans tous les cas, je ne vois pas comment tu vas pouvoir lier ces totaux de flux avec les autres données ... une requête ne peut être à la fois synthétique et détaillée ...

                        -
                        Edité par Benzouye 7 septembre 2020 à 16:32:48

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                          7 septembre 2020 à 17:54:13

                          Désolé benzouy j'ai pas été assez claire avec ma dernière réponse

                          SELECT  semaine
                              ,   SUM(flux_entrant)   AS flux_entrant
                              ,   SUM(flux_sortant)   AS flux_sortant
                              FROM    (   SELECT  WEEKOFYEAR(date_creation)   AS semaine
                                         ,    COUNT(date_creation)        AS flux_entrant
                                         ,    0                           AS  flux_sortant
                                      FROM    affaires , regions
                                      where WEEKOFYEAR(date_creation) IS NOT NULL
                                      AND YEAR(date_creation)='2020'
                                      AND affaires.commune_mes=regions.code_commune
                                       AND  regions.num_cpa='1'
                                      GROUP BY semaine
                                  UNION ALL
                                      SELECT  WEEKOFYEAR(date_cloture)    AS semaine
                                         ,    0                           AS flux_entrant
                                         ,    COUNT(date_cloture)         AS flux_sortant
                                      FROM     affaires , regions
                                      where WEEKOFYEAR(date_cloture) IS NOT NULL
                                      AND YEAR(date_cloture)='2020'
                                      AND affaires.commune_mes=regions.code_commune
                                       AND  regions.num_cpa='1'
                                       GROUP BY semaine
                                              )   AS tmp
                                      GROUP BY semaine
                          
                          
                          


                          voila ce que j'ai pu trouver comme solution

                          pour

                          YEAR(date_creation)='2020'


                          regions.num_cpa='1'

                           actuellement c'est en mais je vais créer un formulaire pour permettre a l'utilisateur de modifier l'année et la cpa

                          -
                          Edité par Massi.dev 7 septembre 2020 à 17:55:24

                          • Partager sur Facebook
                          • Partager sur Twitter

                          banounemassine

                            7 septembre 2020 à 18:28:23

                            Et donc c'est résolu ?

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                              7 septembre 2020 à 18:38:52

                              alors oui a 99%

                              une petite question : pour

                              regions.num_cpa='1'

                              sachant que num_cpa peut etre égal  1 ou 2 ou 3 ou 4 .

                              si l'utilisateur souhaite voir tout les résultats c_a_d ( num_cpa = 1+ num_cpa = 2 + num_cpa = 3  + num_cpa = 4 ) existe-t’il un moyen pour dire a mysql

                              regions.num_cpa = tout

                              • Partager sur Facebook
                              • Partager sur Twitter

                              banounemassine

                                7 septembre 2020 à 21:28:32

                                t'as l'opérateur ensembliste IN qui permet de choisir parmi les valeurs:

                                  AND  regions.num_cpa IN ('1', '2', '3', '4')



                                • Partager sur Facebook
                                • Partager sur Twitter
                                  7 septembre 2020 à 22:32:16

                                  Salut !

                                  Autre point de vue : si un champ peut valoir n'importe laquelle des valeurs qu'il contient, on peut aussi ne pas le mettre dans la requête. Si regions.num_cpa ne contient que les valeurs 1, 2, 3 et 4 et qu'on les veux toutes, autant ne pas mettre de condition.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    7 septembre 2020 à 23:50:04

                                    Merci pour vos réponses .

                                    en fait j'ai deux cas :

                                    cas 1 : l'utilisateur choisit une cpa (1 ou 2 ou 3 ou 4) grace a une liste déroulante  , dans ce cas

                                    regions.num_cpa = (la valeur de la liste déroulante ==>1 ou 2 ou 3 ou 4 )

                                    cas 2 : l'utilisateur ne choisit aucune cpa c-a-d

                                    regions.num_cpa = "" (vide) 

                                    c'est la que ca se complique pour moi car ,  la requête passe pas ==> erreur !!!

                                    donc je cherche un moyen pour dire que quand l'utilisateur ne spécifié pas de cpa ====> prendre toutes  les cpa comme si je fesais ca

                                    ((

                                    regions.num_cpa = 1 and regions.num_cpa = 2 and regions.num_cpa =3 and regions.num_cpa =4

                                    ))

                                    -
                                    Edité par Massi.dev 7 septembre 2020 à 23:51:12

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    banounemassine

                                      8 septembre 2020 à 0:27:37

                                      Je te conseille fortement la lecture du cours MySQL et du doc conception BDD (cf. ma signature).

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                        8 septembre 2020 à 8:14:17

                                        MassineBanoune a écrit:

                                        […] l'utilisateur ne choisit aucune cpa […] prendre toutes les cpa […]

                                        Quitte à m'auto-citer :

                                        Ymox a écrit:

                                        Si regions.num_cpa ne contient que les valeurs 1, 2, 3 et 4 et qu'on les veux toutes, autant ne pas mettre de condition.

                                        Donc si l'utilisateur ne choisit aucune cpa, alors tu n'as pas besoin de lister explicitement toutes les valeurs possibles de ce champ dans la requête, ça revient exactement à la même chose que de ne pas mettre de contrainte sur ce champ.
                                        S'il fallait encore le dire autrement : vouloir tout, c'est la même chose que ne pas vouloir que certaines choses.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          8 septembre 2020 à 18:17:18

                                          Merci infiniment a vous tous ,

                                          je suis désolé j'ai pas l'habitude de poster sur des forums (j'ai du mal a exprimer mon besoin )

                                          mais bon voila la solution que j'ai pu mettre en place (je pense que y a mieux a faire mais bon pas grave)

                                          $sql="SELECT  State
                                              ,   SUM(flux_entrant)   AS flux_entrant
                                              ,   SUM(flux_sortant)   AS flux_sortant
                                              FROM    (   SELECT  
                                          	    			WEEKOFYEAR(date_creation) AS State,
                                          	                COUNT(date_creation) AS flux_entrant,
                                          	                0 AS flux_sortant
                                          		            FROM    happy_mes , regions
                                          		            where WEEKOFYEAR(date_creation) IS NOT NULL
                                          		            AND YEAR(date_creation)=:annee ";
                                          		            if(isset($cpa) && !empty($cpa))
                                          						{
                                          							$q['cpa']=$cpa;
                                          					  		$sql.="AND  regions.num_cpa=:cpa ";
                                          						}
                                          		            $sql.="AND happy_mes.commune_mes=regions.code_commune
                                          		            GROUP BY State
                                          		        UNION ALL
                                          		            SELECT  
                                          		            WEEKOFYEAR(date_cloture) AS State,
                                          		            0 AS flux_entrant,
                                          		            COUNT(date_cloture) AS flux_sortant
                                          		            FROM     happy_mes , regions
                                          		            where WEEKOFYEAR(date_cloture) IS NOT NULL
                                          		            AND YEAR(date_cloture)=:annee ";
                                          		            if(isset($cpa) && !empty($cpa))
                                          						{
                                          							$q['cpa']=$cpa;
                                          					  		$sql.="AND  regions.num_cpa=:cpa ";
                                          						}
                                          		            $sql.= "AND happy_mes.commune_mes=regions.code_commune
                                          		            GROUP BY State ) AS tmp
                                          		            GROUP BY State ";



                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          banounemassine

                                          Plusieurs champs COUNT, GROUP BY

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown