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

Développement SQL Server Discussion :

Comment faire une somme conditionnelle ?


Sujet :

Développement SQL Server

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Comment faire une somme conditionnelle ?
    Bonsoir,
    Alors Depuis ce matin je n'arrive pas à créer une requete qui permet de faire la chose suivante :
    J'ai une première table TOTO qui recense le nombre d'habitants par tranche d'age (Plage_Sup) avec les champs suivants :
    Pays Plage_Sup Nb_Personnes
    Fr 5 100
    Fr 10 5000
    Fr 15 14500
    Fr 20 500
    Fr 25 6000
    Fr 30 5000
    Fr 35 1000
    Fr 40 500
    Fr 50 10000
    C'est à dire qu'en France, il y a 100 habitants qui ont entre 0 et 5 ans, 5000 habitants ayant entre 5 (intervalle ouvert) et 10 ans (intervalle fermé), etc ... (pas besoin de vous dire que les chiffres ne sont pas du tout réalistes, mais bon je n'ai pas trouvé un autre exemple plus concret :-P)

    J'ai une 2ème table TATA qui redéfinit les intervalles d'age, avec :
    Pays Plage_Sup
    Fr 5
    Fr 20
    Fr 30
    Fr 35
    Fr 50

    Mon objectif est de réaffecter les habitants en respectant le paramétrage de la nouvelle table, tout en faisant des sommes sur les plages supérieures disponibles dans cette table, c'est à dire, à la fin du traitement je devrai avoir le résultat suivant :
    Table TATA avec ne nouveau champ Nb_Personnes_Bis :

    Pays Plage_Sup Nb_Personnes_Bis
    Fr 5 100
    Fr 20 20000 ( = 5000+14500+500)
    Fr 30 11000 (= 6000+5000)
    Fr 35 1000
    Fr 50 10500

    J'ai tout essayé pour faire ça via SQL mais je n'arrive pas :-(
    Avez vous une piste SVP ??

    Merci !!
    Céline

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'ai tout essayé
    Qu'avez-vous essayé ?
    Avec quel SGBD ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Qu'avez-vous essayé ?
    Avec quel SGBD ?
    Bonjour CinePhil,
    Mon SGBD est SQL Server,
    La solution que j'ai trouvée (en théorie) est la suivante : rajouter un nouveau champ "Plage_Sup_New" dans la table TOTO comme suit :tant que ma Plage_Sup initiale est inférieure ou égale à la Plage_Sup_2 da la table TATA j'alimente le nouveau champ Plage_Sup_New avec la nouvelle Borne supérieure. Concretement voici ce que je devrai avoir dans ma table TOTO :
    Pays Plage_Sup Nb_Personnes Plage_Sup_New
    Fr 5 100 5
    Fr 10 5000 20
    Fr 15 14500 20
    Fr 20 500 20
    Fr 25 6000 30
    Fr 30 5000 30
    Fr 35 1000 35
    Fr 40 500 50
    Fr 50 10000 50


    Après je fais un Group By Plage_Sup_New pour trouver le nombre d'habitants suivant le nouvelle structure de plages.
    Techniquement je n'arrive pas à faire ce que je veux :-(((
    Any help ?
    A dispo si question ..

    Merci
    Celine

  4. #4
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    que pensez vous de qlq chose comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select 
    C.Pays, C.plage_REF, sum(C.Nb_Personnes)
    from (
    	select A.*, min(B.plage_sup) as plage_REF
    	from TOTO A 
    	inner join TATA B on A.Plage_Sup <= B.plage_sup and A.Pays = B.Pays
        group by A.Pays, A.Plage_Sup, A.Nb_Personnes
        ) C 
    group by C.Pays, C.plage_REF

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Ou sinon si la version de Sql Server le permet, on peut utiliser LAG :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      with tata_prev as (
    select pays, Plage_Sup, lag(Plage_Sup) over(partition by pays order by Plage_Sup) as prev_plage_sup
      from tata
    )
    select tp.pays, tp.Plage_Sup, sum(t.Nb_Personnes) as Nb_Personnes
      from tata_prev tp
      join toto t
        on t.pays = tp.pays
       and t.Plage_Sup > coalesce(tp.prev_plage_sup,0)
       and t.Plage_Sup <= tp.Plage_Sup
     group by tp.pays, tp.Plage_Sup
     order by tp.pays, tp.Plage_Sup

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Sinon, ça aussi ça marche (et devrait marcher sous n'importe quel SGBD)
    Code sql : 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    /* Jeu de données si on n'a pas les tables dans la base de données
    with toto (Pays, Plage_Sup, Nb_Personnes) as
    (
    	select 'Fr', 5, 100
    	union all
    	select 'Fr', 10, 5000
    	union all
    	select 'Fr', 15, 14500
    	union all
    	select 'Fr', 20, 500
    	union all
    	select 'Fr', 25, 6000
    	union all
    	select 'Fr', 30, 5000
    	union all
    	select 'Fr', 35, 1000
    	union all
    	select 'Fr', 40, 500
    	union all
    	select 'Fr', 50, 10000
    ),
    tata (Pays, Plage_Sup) as
    (
    	select 'Fr', 5
    	union all
    	select 'Fr', 20
    	union all
    	select 'Fr', 30
    	union all
    	select 'Fr', 35
    	union all
    	select 'Fr', 50
    )
    */
    select to2.pays, tmp.plage_sup, sum(to2.nb_personnes) nb
    from toto to2
    inner join (
    	select ta1.pays, ta1.Plage_Sup, coalesce(max(ta2.plage_sup), 0) m
    	from tata ta1
    	left outer join tata ta2 on ta2.pays = ta1.pays and ta2.Plage_Sup < ta1.Plage_Sup
    	group by ta1.pays, ta1.Plage_Sup
    ) tmp on tmp.Pays = to2.Pays and to2.Plage_Sup > m and to2.Plage_Sup <= tmp.Plage_Sup
    group by to2.pays, tmp.plage_sup;
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par bstevy Voir le message
    que pensez vous de qlq chose comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select 
    C.Pays, C.plage_REF, sum(C.Nb_Personnes)
    from (
    	select A.*, min(B.plage_sup) as plage_REF
    	from TOTO A 
    	inner join TATA B on A.Plage_Sup <= B.plage_sup and A.Pays = B.Pays
        group by A.Pays, A.Plage_Sup, A.Nb_Personnes
        ) C 
    group by C.Pays, C.plage_REF
    Merci beaucoup bstevy pour ta solution qui fonctionne bien :-)
    j'ai testé la solution 3 qui donne des résultats faux.

    Merci à vous tous :-)

    C.

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Solution 3 : la mienne ?

    Voici pourtant ce que ça retourne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    pays plage_sup   nb
    ---- ----------- -----------
    Fr   5           100
    Fr   20          20000
    Fr   30          11000
    Fr   35          1000
    Fr   50          10500
    Warning: Null value is eliminated by an aggregate or other SET operation.
     
    (5 row(s) affected)
    Ce qui correspond exactement à votre demande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Pays Plage_Sup Nb_Personnes_Bis
    Fr 5 100
    Fr 20 20000 ( = 5000+14500+500)
    Fr 30 11000 (= 6000+5000)
    Fr 35 1000
    Fr 50 10500
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. COmment faire une SOMME
    Par Lucas42 dans le forum C++
    Réponses: 5
    Dernier message: 10/11/2007, 11h38
  2. Réponses: 13
    Dernier message: 05/11/2007, 09h00
  3. Faire une somme conditionnelle
    Par pilpoil dans le forum Excel
    Réponses: 6
    Dernier message: 10/08/2007, 14h46
  4. Réponses: 3
    Dernier message: 09/05/2007, 11h43
  5. Réponses: 10
    Dernier message: 03/10/2006, 20h19

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