IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Subquery et clause IN


Sujet :

Langage SQL

  1. #1
    Membre habitué Avatar de aelmalki
    Inscrit en
    Mars 2009
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 250
    Points : 125
    Points
    125
    Par défaut Subquery et clause IN
    Bonjour,

    Prenant l'exemple de cette requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    SELECT personne.IDPERSONNE, 
    	(SELECT SUM(enfantDate.alloc) 
    	FROM PERSONNE personneDate LEFT JOIN ENFANT enfantDate
    		ON personneDate.IDPERSONNE=enfantDate.PERSONNE_ID 
    		AND enfantDate.DATEDEBUT = '2000-05-01' 
    	WHERE personneDate.IDPERSONNE = 4) as sumAllocationParDate,
     
    	(SELECT SUM(enfantParPeriode.alloc) 
    	FROM PERSONNE personneParPeriode LEFT JOIN ENFANT enfantParPeriode
    		ON personneParPeriode.IDPERSONNE=enfantParPeriode.PERSONNE_ID 
    		AND enfantParPeriode.DATEFIN > '2000-01-01' AND enfantParPeriode.DATEFIN < '2000-06-01'
    	WHERE personneParPeriode.IDPERSONNE = 4) as sumAllocationParPeriode
     
    FROM PERSONNE personne 
    WHERE personne.IDPERSONNE = 4;
    Je n'arrive pas à utiliser le IN pour avoir les allocations d'un ensemble de personne par date et par période, cette requête ne fonctionne pas puisque le retour des subquery est un ensemble de ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    SELECT personne.IDPERSONNE, 
    	(SELECT SUM(enfantDate.alloc) 
    	FROM PERSONNE personneDate LEFT JOIN ENFANT enfantDate
    		ON personneDate.IDPERSONNE=enfantDate.PERSONNE_ID 
    		AND enfantDate.DATEDEBUT = '2000-05-01' 
    	WHERE personneDate.IDPERSONNE  IN (1,2,3,4)) as sumAllocationParDate,
     
    	(SELECT SUM(enfantParPeriode.alloc) 
    	FROM PERSONNE personneParPeriode LEFT JOIN ENFANT enfantParPeriode
    		ON personneParPeriode.IDPERSONNE=enfantParPeriode.PERSONNE_ID 
    		AND enfantParPeriode.DATEFIN > '2000-01-01' AND enfantParPeriode.DATEFIN < '2000-06-01'
    	WHERE personneParPeriode.IDPERSONNE  IN (1,2,3,4)) as sumAllocationParPeriode
     
    FROM PERSONNE personne 
    WHERE personne.IDPERSONNE IN (1,2,3,4);
    Que dois je modifier dans ma requête pour avoir le résultat souhaité ?

    Merci beaucoup pour votre aide.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 099
    Points : 28 390
    Points
    28 390
    Par défaut
    Il faut que tes sous-requêtes scalaires soient liées à la requête principale.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    SELECT  personne.IDPERSONNE
        ,   (   SELECT  SUM(enfantDate.alloc) 
                FROM    PERSONNE    personneDate 
                    LEFT JOIN 
                        ENFANT      enfantDate
                        ON  personneDate.IDPERSONNE = enfantDate.PERSONNE_ID 
                        AND enfantDate.DATEDEBUT = '2000-05-01' 
                WHERE personneDate.IDPERSONNE = personne.IDPERSONNE
            )   AS  sumAllocationParDate
        ,   (   SELECT  SUM(enfantParPeriode.alloc) 
                FROM    PERSONNE    personneParPeriode 
                    LEFT JOIN 
                        ENFANT      enfantParPeriode
                        ON  personneParPeriode.IDPERSONNE = enfantParPeriode.PERSONNE_ID 
                        AND enfantParPeriode.DATEFIN > '2000-01-01' 
                        AND enfantParPeriode.DATEFIN < '2000-06-01'
                WHERE   personneParPeriode.IDPERSONNE = personne.IDPERSONNE
            )   AS  sumAllocationParPeriode
     
    FROM    PERSONNE personne 
    WHERE   personne.IDPERSONNE IN (1,2,3,4)
    ;

  3. #3
    Membre habitué Avatar de aelmalki
    Inscrit en
    Mars 2009
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 250
    Points : 125
    Points
    125
    Par défaut
    C'est parfait.
    Merci infiniment.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Les sous-requête scalaires je les lirais directement avec la table personne de la requête principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT personne.IDPERSONNE, 
    	     (SELECT SUM(enfantDate.alloc) 
    	        FROM ENFANT enfantDate
    		     where enfantDate.PERSONNE_ID = personne.IDPERSONNE
    		       AND enfantDate.DATEDEBUT = '2000-05-01' 
    	     ) AS sumAllocationParDate, 
    	     (SELECT SUM(enfantParPeriode.alloc) 
    	        FROM ENFANT enfantParPeriode
    		     where enfantParPeriode.PERSONNE_ID = personne.IDPERSONNE
    		       AND enfantParPeriode.DATEFIN > '2000-01-01' AND enfantParPeriode.DATEFIN < '2000-06-01'
    	     ) AS sumAllocationParPeriode 
      FROM PERSONNE personne 
     WHERE personne.IDPERSONNE IN (1,2,3,4);
    Ou sinon passer par des sommes conditionnées :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT p.IDPERSONNE 
    	   , sum(case when DATEDEBUT = '2000-05-01' 
                    then e.alloc 
                end ) as sumAllocationParDate
    	   , sum(case when enfantParPeriode.DATEFIN > '2000-01-01' 
                     AND enfantParPeriode.DATEFIN < '2000-06-01' 
                    then e.alloc 
                end ) as sumAllocationParPeriode 
      FROM PERSONNE p
      left join ENFANT e on e.PERSONNE_ID = p.IDPERSONNE
     where p.IDPERSONNE IN (1,2,3,4)
     group by p.IDPERSONNE
    Ca devrait donner le même résultat en plus performant, non ?

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 099
    Points : 28 390
    Points
    28 390
    Par défaut
    Tu peux aussi reporter tes calculs dans des tables dérivées :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    SELECT  prs.idpersonne
        ,   edt.somme   AS  sumAllocationParDate
        ,   epr.somme   AS  sumAllocationParPeriode
    FROM    PERSONNE prs
        LEFT JOIN
            (   SELECT  enf.personne_id
                    ,   SUM(enf.alloc)  AS  somme
                FROM    enfant  enf
                WHERE   enf.datedebut = '2000-05-01'
                GROUP BY enf.personne_id
            )   edt
            ON  prs.idpersonne = edt.personne_id
        LEFT JOIN
            (   SELECT  enf.personne_id
                    ,   SUM(enf.alloc)  AS  somme
                FROM    enfant
                WHERE   enf.datefin > '2000-01-01' 
                    AND enf.datefin < '2000-06-01'
                GROUP BY enf.personne_id
            )   epr
            ON  prs.idpersonne = epr.personne_id 
    WHERE   prs.idpersonne IN (1,2,3,4)
    ;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [11gR2] Oracle subquery dans une clause FROM
    Par Vodsky dans le forum SQL
    Réponses: 7
    Dernier message: 06/06/2014, 13h41
  2. Réponses: 3
    Dernier message: 11/03/2004, 10h58
  3. [ character en simple cote ] clause Where
    Par hocinema dans le forum DB2
    Réponses: 3
    Dernier message: 20/02/2004, 10h17
  4. SYBASE SELECT imbriqué clause FROM
    Par Nicolas Martel dans le forum Sybase
    Réponses: 2
    Dernier message: 19/11/2003, 15h28
  5. Probleme dans une clause like !
    Par adil dans le forum Langage SQL
    Réponses: 6
    Dernier message: 15/07/2003, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo