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 :

Update + SUM + Group BY


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut Update + SUM + Group BY
    J’ai une tableA ayant la structure suivante :

    ID1 ID2 Valeur
    1 11 10
    1 11 10
    2 22 15
    2 22 15

    Les colonnes (ID1, ID2 & Valeur) sont déjà renseignées.

    Le besoin est de sommer la "Valeur" par "ID1" et "ID2" et la mettre dans la colonne "Valeur_Total" (Update)

    càd la colonne "Valeur_Total" sera comme suit :

    Valeur_Totale
    20
    20
    30
    30

    J’ai fais cette requête, mais ça marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Update TableA
    Set Valeur_Total = (
      select  sum(Valeur)  
      from  TableA  
      group by  ID1, ID2
    )
    merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Un truc comme ça devrait marcher :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Update TableA a
    Set Valeur_Total = (select sum(Valeur) from TableA where id1 = A.ID1 and ID2 = A.ID2)

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Bonjour,

    merci tomlev..

    l'exécution de ta requête a sommé toutes les valeurs sans grouper
    par ID1 et ID2

    ID1--ID2----Valeur------ValeurTotale
    1----11 -----10 ---------50
    1----11 -----10 ---------50
    2----22 -----15 ---------50
    2----22 -----15 ---------50

    alors que je souhaite avoir la somme comme il suit :

    ID1--ID2----Valeur------ValeurTotale
    1----11 -----10 ---------20
    1----11 -----10 ---------20
    2----22 -----15 ---------30
    2----22 -----15 ---------30

    je pense qu'il est essentiel d'ajouter un Group By (ID1 et ID2) dans la requête mais sans que ça soit ajouter dans le Select ...

    si vous avez une idée de comment peut on faire ceci...
    merci d'avance

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE tableA
    INNER JOIN (
        SELECT ID1, ID2, SUM(Valeur) AS somme_valeur
        FROM tableA
        GROUP BY ID1, ID2
    ) tmp ON tableA.ID1 = tmp.ID1 AND tableA.ID2 = tmp.ID2
    SET tableA.Valeur_Total = tmp.somme_valeur
    Si ça ne fonctionne pas à cause du fait que la sous-requête porte sur la table qui doit être mise à jour, fais de cette sous-requête une table temporaire et fais la jointure avec la table temporaire, éventuellement après l'avoir indexée si le volume de données à traiter est gros.
    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 !

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Bizarre, je ne vois pas comment c'est possible que ça ait sommé toutes les valeurs Tu as copié la requête exactement ou tu as l'as modifiée ?

    Au fait tu utilises quoi comme SGBD ? La requête que je t'ai donnée devrait marcher sous Oracle, mais pas forcément sur d'autres SGBD... Je viens de tester sur SQLite et SQL Server (Express et CE), aucun n'accepte d'alias sur la table mise à jour

  6. #6
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Bizarre, je ne vois pas comment c'est possible que ça ait sommé toutes les valeurs Tu as copié la requête exactement ou tu as l'as modifiée ?

    Au fait tu utilises quoi comme SGBD ? La requête que je t'ai donnée devrait marcher sous Oracle, mais pas forcément sur d'autres SGBD... Je viens de tester sur SQLite et SQL Server (Express et CE), aucun n'accepte d'alias sur la table mise à jour

    j'utilise SQL Server 2008 : donc effectivement n'accepte d'alias sur la table mise à jour, et donc j'ai mis l'alias dans le Select :

    UPDATE TableA
    SET Valeur_Total = (SELECT sum(a.Valeur) FROM TableA a WHERE id1 = A.ID1 AND ID2 = A.ID2)

  7. #7
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    j'ai exécuté cette requête :

    Citation Envoyé par CinePhil Voir le message
    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE tableA
    INNER JOIN (
        SELECT ID1, ID2, SUM(Valeur) AS somme_valeur
        FROM tableA
        GROUP BY ID1, ID2
    ) tmp ON tableA.ID1 = tmp.ID1 AND tableA.ID2 = tmp.ID2
    SET tableA.Valeur_Total = tmp.somme_valeur
    comme résultat il affiche 2 erreurs :

    Incorrect syntax near the keyword 'INNER'.
    Incorrect syntax near 'tmp'.

    comment faire de la sous-requête une table temporaire ?!!!
    merci de m'indiquer la structure de la requête.

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par laure07 Voir le message
    comme résultat il affiche 2 erreurs :

    Incorrect syntax near the keyword 'INNER'.
    cela voudrait dire que ton outil ne connaît pas la syntaxe normalisée pour les jointures depuis 1999 ?
    => Jette-le !

    Incorrect syntax near 'tmp'.
    Et en plus il ne semble pas supporter les sous-requêtes !
    => Ressort le de la poubelle, casse-le, jette les morceaux !

    Pourtant :
    j'utilise SQL Server 2008
    Bizarre que ça plante !
    N'ayant jamais utilisé le SGBD paraît-il super génial de Petitmou, je ne peux t'aider davantage !
    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 !

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par laure07 Voir le message
    j'utilise SQL Server 2008 : donc effectivement n'accepte d'alias sur la table mise à jour, et donc j'ai mis l'alias dans le Select :

    UPDATE TableA
    SET Valeur_Total = (SELECT sum(a.Valeur) FROM TableA a WHERE id1 = A.ID1 AND ID2 = A.ID2)
    Ah ben c'est normal alors, ça n'a plus du tout le même sens... avec la modification que tu as apportée, la condition dans le WHERE est vraie pour toutes les lignes, d'où le résultat que tu obtiens.

    Je ne suis pas sûr que tu puisse faire ça en une seule requête avec SQL Server. Par contre tu peux toujours faire une procédure stockée, ce serait assez simple (il suffit d'une boucle sur le résultat du SELECT ... GROUP BY)

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    cela voudrait dire que ton outil ne connaît pas la syntaxe normalisée pour les jointures depuis 1999 ?
    => Jette-le !

    Et en plus il ne semble pas supporter les sous-requêtes !
    => Ressort le de la poubelle, casse-le, jette les morceaux !
    SQL Server supporte tout à fait la syntaxe de jointure normalisée et les sous requêtes... c'est juste qu'on ne peut pas faire de jointure dans un UPDATE (ni avec SQL Server ni avec aucun autre SGBD il me semble...)

  11. #11
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Je ne suis pas sûr que tu puisse faire ça en une seule requête avec SQL Server. Par contre tu peux toujours faire une procédure stockée, ce serait assez simple (il suffit d'une boucle sur le résultat du SELECT ... GROUP BY)[/QUOTE]

    merci tomlev pour ta réactivité ...
    pourra tu stp m'indiquer la structure de la procédure stocké
    merci d'avance

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    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 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par tomlev Voir le message
    SQL Server supporte tout à fait la syntaxe de jointure normalisée et les sous requêtes...
    D'où mon étonnement !
    c'est juste qu'on ne peut pas faire de jointure dans un UPDATE (ni avec SQL Server ni avec aucun autre SGBD il me semble...)
    Il me semble pourtant l'avoir fait avec MySQL. Pas le temps de tester maintenant.
    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 !

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par laure07 Voir le message
    pourra tu stp m'indiquer la structure de la procédure stocké
    A vrai dire je ne connais pas la syntaxe des procédures stockées en SQL Server, donc tout ce que je peux te donner, c'est du pseudo-code...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Pour chaque ligne dans (SELECT ID1, ID2, SUM(Valeur) AS somme_valeur FROM TableA GROUP BY ID1, ID2)
            UPDATE TableA SET Valeur_Total = ligne.somme_valeur WHERE ID1 = ligne.ID1 AND ID2 = ligne.ID2
        Fin Pour

  14. #14
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    Pas besoin d'une procédure, la solution a été quasiment donnée par l'auteur.
    Il faut juste donner un petit coup de pouce à SQL-Server avec les noms de table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE TableA
       SET Valeur_Total = (SELECT sum(TA.Valeur)
                             FROM TableA as TA
                            WHERE TA.ID1 = TableA.ID1
                              AND TA.ID2 = TableA.ID2);

  15. #15
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Merciiiiiiiiiiii Waldar ... ca marche nickel ... Merci beaucoup ... vraiment

  16. #16
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 778
    Points
    30 778
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    cela voudrait dire que ton outil ne connaît pas la syntaxe normalisée pour les jointures depuis 1999 ?
    Cela veut simplement dire qu'il respecte la syntaxe normalisée (ANSI-2003) de la commande UPDATE, qui ne prévoit pas de clause de jointure...

    et que MySQL ne respecte pas cette norme, mais ça tout le monde le sait
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  17. #17
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Citation Envoyé par tomlev Voir le message
    A vrai dire je ne connais pas la syntaxe des procédures stockées en SQL Server, donc tout ce que je peux te donner, c'est du pseudo-code...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Pour chaque ligne dans (SELECT ID1, ID2, SUM(Valeur) AS somme_valeur FROM TableA GROUP BY ID1, ID2)
            UPDATE TableA SET Valeur_Total = ligne.somme_valeur WHERE ID1 = ligne.ID1 AND ID2 = ligne.ID2
        Fin Pour
    @ tomlev : Merci bcp pour ta réponse

  18. #18
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Re bonjour,

    concernant la même requête :

    je vous rappelle que :
    j'ai une tableA ayant la structure suivante :

    ID ---- Année---- Valeur ---- ValeurTotat
    1 ---- 2004 ------ 10
    1 ---- 2004 ------ 20
    2 ---- 2005 ------ 30
    2 ---- 2005 ------ 40
    le champ "ValeurTotat" (somme du champ "valeur" par Année et ID) est vide dans un premier temps, pour le renseigner j'effectue un Update sur la tableA.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Update TableA
    Set ValeurTotat = (Select sum(TA.valeur)
    From TableA TA
    Where TA.ID = TableA.ID
    AND TA.Année = TableA.Année
    AND TA.Année = 2004)
    ce qui va donner :
    ID ---- Année---- Valeur ---- ValeurTotat
    1 ---- 2004 ------ 10 ------ 30
    1 ---- 2004 ------ 20 ------ 30
    2 ---- 2005 ------ 30
    2 ---- 2005 ------ 40
    pour question de volumétrie de la BD, je fais le Update année par année.

    le Update s'effectue correctement pour le 2004; mais quand je vais exécuter le même Update pour 2005, la mise à jour sera bien faite sauf que la ValeurTotal de l'année 2004 que j'ai effectué au début aura Null comme valeur.

    ID ---- Année---- Valeur ---- ValeurTotat
    1 ---- 2004 ------ 10 ------ Null
    1 ---- 2004 ------ 20 ------ Null
    2 ---- 2005 ------ 30 ------ 70
    2 ---- 2005 ------ 40 ------ 70


    je ne comprends pas pourquoi?

    Merci d'avance

  19. #19
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Manque une clause where dans votre update.

    Là vous updatez toute votre table systématiquement.

  20. #20
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    431
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 431
    Points : 79
    Points
    79
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Manque une close where dans votre update.

    La vous updatez toute votre table systématiquement.

    c'est réglé ..merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/10/2010, 15h00
  2. update + sum + group by
    Par PhYx dans le forum Langage SQL
    Réponses: 5
    Dernier message: 12/06/2008, 16h44
  3. requete sql deux fois sum groupe by
    Par DIDIDIDA dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/03/2008, 14h04
  4. Update + SUM() ?
    Par dark_vidor dans le forum Langage SQL
    Réponses: 6
    Dernier message: 03/01/2006, 23h51
  5. update avec group by
    Par slc dans le forum Requêtes
    Réponses: 4
    Dernier message: 05/10/2004, 14h44

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