Partage
  • Partager sur Facebook
  • Partager sur Twitter

Faire un count en sous-requête

    20 janvier 2021 à 11:11:28

    Bonjour, 

    J'essaie de faire une requête pour afficher les champs entre différentes tables, aucun souci à ce niveau la.. Mais c'est quand je veux compter pour chaque ligne le nombre d'appels reçus, la j'ai de petits problèmes. Voici la requête actuelle 

    select *,(select count(*) from calllogs where direction like 'inbound' group by todest,toextension,result) as b
    from(
    			select todest,toextension,firstName,lastName,email,site
                from calllogs
                JOIN phonenumber
                ON phonenumber.phonenumber = calllogs.todest
                JOIN extension
                ON extension.id = phonenumber.extensionid 
                where direction like 'inbound' and result like 'Missed' group by todest,toextension,firstName,lastName,email,site
                except
                select todest,toextension,firstName,lastName,email,site
                from calllogs
                JOIN phonenumber
                ON phonenumber.phonenumber = calllogs.todest
                JOIN extension
                ON extension.id = phonenumber.extensionid  
                where direction like 'inbound' and result like 'Accepted' group by todest,toextension,firstName,lastName,email,site) A

    Et l'erreur que ça m'indique :

    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    

    Merci d'avance pour votre aide.

    • Partager sur Facebook
    • Partager sur Twitter
      20 janvier 2021 à 18:02:40

      Bonjour,

      Ouch ... un réapprentissage du SQL me semble nécessaire ici ...

      Comment as-tu généré cette requête tortueuse ?

      Dans ton exemple l'utilisation de GROUP BY pour les 2 requêtes de la clause FROM est inutile, pour supprimer les doublons c'est DISTINCT qu'il faut utiliser ...

      On ne met jamais de SELECT imbriqués, sauf cas très très très particuliers, au risque de mettre le serveur à genoux, car il doit réévaluer le SELECT imbriqué pour chaque enregistrement.

      De plus ici ton SELECT imbriqué va retourner plusieurs valeurs pour chaque ligne (c'est l'erreur retournée d'ailleurs) ...

      Pour pouvoir t'aider, peux-tu préciser la structure (colonnes et types) des trois tables en jeu ?

      Peux-tu également écrire en français (en toutes lettres) ce que tu cherches à faire ? Exemple "Je veux la liste des numéros dont l'appel a manqué (missed) pour la direction inbound et qui n'ont pas été accepté par ailleurs, avec pour chaque numéros concerné le nombre d'appel manqué".

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        21 janvier 2021 à 9:15:45

        Benzouye a écrit:

        Bonjour,

        Ouch ... un réapprentissage du SQL me semble nécessaire ici ...

        Comment as-tu généré cette requête tortueuse ?

        Dans ton exemple l'utilisation de GROUP BY pour les 2 requêtes de la clause FROM est inutile, pour supprimer les doublons c'est DISTINCT qu'il faut utiliser ...

        On ne met jamais de SELECT imbriqués, sauf cas très très très particuliers, au risque de mettre le serveur à genoux, car il doit réévaluer le SELECT imbriqué pour chaque enregistrement.

        De plus ici ton SELECT imbriqué va retourner plusieurs valeurs pour chaque ligne (c'est l'erreur retournée d'ailleurs) ...

        Pour pouvoir t'aider, peux-tu préciser la structure (colonnes et types) des trois tables en jeu ?

        Peux-tu également écrire en français (en toutes lettres) ce que tu cherches à faire ? Exemple "Je veux la liste des numéros dont l'appel a manqué (missed) pour la direction inbound et qui n'ont pas été accepté par ailleurs, avec pour chaque numéros concerné le nombre d'appel manqué".


        Oui ça fait un moment que je n'ai pas fait de sql donc c'est assez brouillon désolé...

        table calllogs :

        table phonenumber :

        table extension :

        et la requête que j'ai modifiée depuis hier, j'ai enlevé le count qui ne marchait pas et j'ai récupérer autre chose (le dernier appel reçu) : 

        select a.todest,a.Usertype,a.firstName,a.lastName,a.email,a.site,c.starttime
                    from calllogs as c
                    join (
                    select todest, max(starttime) as datemax
                    from calllogs
                    group by todest) tmp on tmp.todest = c.todest
                    join(select distinct todest,toextension,firstName,lastName,email,site,Usertype
                                from calllogs
                                JOIN phonenumber
                                ON phonenumber.phonenumber = calllogs.todest
                                JOIN extension
                                ON extension.id = phonenumber.extensionid 
                                where direction like 'inbound' and result like 'Missed' and (firstName!='' or lastName!='')
                                group by todest,toextension,firstName,lastName,email,site,Usertype
                                except
                                select todest,toextension,firstName,lastName,email,site,Usertype
                                from calllogs
                                JOIN phonenumber
                                ON phonenumber.phonenumber = calllogs.todest
                                JOIN extension
                                ON extension.id = phonenumber.extensionid  
                                where direction like 'inbound' and result like 'Accepted' and (firstName!='' or lastName!='')
                    ) a on a.todest=c.todest
                    where c.starttime = tmp.datemax and starttime between dateadd(month,-3,getdate()) and getdate()
                    order by a.firstName

        Qui est peut-être encore plus brouillon ^^'

        Et ce que je veux :

        Récupérer todest (numéro appelé), usertype du numéro appelé, prénom dans extension lié au numéro avec la table phonenumber, nom, email et site pareil que le prénom ou l'utilisateur a manqué a des appels manqués (direction inbound et result missed) et aucun accepté (inbound accepted). Et pour chaque numéro concerné, la date du dernier appel reçu (max starttime) et le nombre d'appels reçus (inbound) uniquement dans les 3 derniers mois.

        J'espère que c'est plus clair.

        -
        Edité par VincentLaclide 21 janvier 2021 à 9:36:04

        • Partager sur Facebook
        • Partager sur Twitter
          21 janvier 2021 à 12:16:02

          Oui, c'est bien plus clair :)

          Je te propose de grandement simplifier tout cela.

          SELECT
          	C.todest,
          	E.Usertype,
          	E.firstName,
          	E.lastName,
          	E.email,
          	E.site,
          	MAX( C.starttime ) AS last_call,
          	COUNT(*) AS nb_calls
          FROM
          	calllogs C
          		INNER JOIN phonenumber N
          			ON N.phonenumber = C.todest
          		INNER JOIN extension E
          			ON E.id = N.extensionid
          		LEFT JOIN calllogs AC
          			ON C.todest = AC.todest
          			AND AC.result = 'Accepted'
          WHERE
          	C.result = 'Missed'
          	AND C.direction = 'inbound'
          	AND AC.phonenumber IS NULL
          	AND C.starttime BETWEEN DATEADD( MONTH, -3, GETDATE() ) AND GETDATE()
          GROUP BY
          	C.todest,
          	E.Usertype,
          	E.firstName,
          	E.lastName,
          	E.email,
          	E.site

          -
          Edité par Benzouye 21 janvier 2021 à 12:36:11

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            21 janvier 2021 à 12:29:55

            Benzouye a écrit:

            Oui, c'est bien plus clair :)

            Je te propose de grandement simplifier tout cela.

            SELECT
            	C.todest,
            	E.Usertype,
            	E.firstName,
            	E.lastName,
            	E.email,
            	E.site,
            	MAX( C.starttime ) AS last_call,
            	COUNT(*) AS nb_calls
            FROM
            	calllogs C
            		INNER JOIN phonenumber N
            			ON N.phonenumber = C.todest
            		INNER JOIN extension E
            			ON E.id = N.extensionid
            		LEFT JOIN calllogs AC
            			ON C.todest = AC.phonenumber
            			AND AC.result = 'Accepted'
            WHERE
            	C.result = 'Missed'
            	AND C.direction = 'inbound'
            	AND AC.phonenumber IS NULL
            	AND C.starttime BETWEEN DATEADD( MONTH, -3, GETDATE() ) AND GETDATE()
            GROUP BY
            	C.todest,
            	E.Usertype,
            	E.firstName,
            	E.lastName,
            	E.email,
            	E.site
            Ça à l'air bien plus clair effectivement, merci beaucoup. Seulement il ne trouve pas phonenumber dans la table AC (normal puisque ce champs n'est pas dans la table calllogs). Donc je vais essayer de rectifier cela mais si tu as la solution avant je suis preneur ^^. Ou alors il y a un truc qui m'échappe peut-être.

            -
            Edité par VincentLaclide 21 janvier 2021 à 12:34:02

            • Partager sur Facebook
            • Partager sur Twitter
              21 janvier 2021 à 12:35:58

              VincentLaclide a écrit:

              il ne trouve pas phonenumber dans la table AC (normal puisque ce champs n'est pas dans la table calllogs)

              Oui, erreur de ma part, j'ai édité mon message précédent.

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                21 janvier 2021 à 13:49:39

                Benzouye a écrit:

                Oui, erreur de ma part, j'ai édité mon message précédent.


                Yes merci beaucoup (tu en as oublié un mais c'est bon). C'est vrai que c'est beaucoup plus propre et je récupère quasiment les mêmes données, la différence étant (je crois) que tu prends le dernier appel reçu seulement parmi les appels manqués et non pas parmi tout type d'appel. Enfin c'est pas dérangeant.

                Je met la requête finale ici :

                SELECT
                    C.todest,
                    E.Usertype,
                    E.firstName,
                    E.lastName,
                    E.email,
                    E.site,
                    MAX( C.starttime ) AS last_call,
                    COUNT(*) AS nb_calls
                FROM
                    calllogs C
                        INNER JOIN phonenumber N
                            ON N.phonenumber = C.todest
                        INNER JOIN extension E
                            ON E.id = N.extensionid
                        LEFT JOIN calllogs AC
                            ON C.todest = AC.todest
                            AND AC.result = 'Accepted'
                WHERE
                    C.result = 'Missed'
                    AND C.direction = 'inbound'
                    AND AC.todest IS NULL
                	AND (firstName!='' OR lastName!='')
                    AND C.starttime BETWEEN DATEADD( MONTH, -3, GETDATE() ) AND GETDATE()
                GROUP BY
                    C.todest,
                    E.Usertype,
                    E.firstName,
                    E.lastName,
                    E.email,
                    E.site
                ORDER BY
                	nb_calls DESC



                • Partager sur Facebook
                • Partager sur Twitter

                Faire un count en sous-requête

                × 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