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 et Jointure, impossible ?


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club

    Inscrit en
    Octobre 2007
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 33
    Points : 36
    Points
    36
    Par défaut Update Sum et Jointure, impossible ?
    Je veux faire quelque chose qui me semble classique : mettre à jour un champ dans une table en cumulant les valeurs d'un champ d'une table liée
    J'utilise Access 2003, mais j'ai vu plusieurs messages sur le même problème concernant d'autres bases de données.

    Soit une table A avec pour champs Clef et Total
    et une table B avec pour champs Clef, Clef_A et Valeur
    la jointure se faisant entre A.Clef et B.Clef_A

    Access me génère la requête suivante (qui me parait pas mal):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE a INNER JOIN b ON a.Clef = b.Clef_A SET a.Total = Sum([Valeur]);
    mais me donne le message d'erreur suivant :
    Vous avez essayé d'exécuter une requête ne comprenant pas l'expression spécifiée 'Total' comme une partie de la fonction d'agrégat

    Sur les forums on trouve des conseils du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE a SET a.Total = (select sum(b.Valeur) from b where  a.Clef = b.Clef_A);
    Qui ne donnent pas de satisfaction (sur les forums)
    et me donnent l'erreur :
    L'opération doit utiliser une requête qui peut être mise à jour

    Même message en créant une requête de sélection dont on se sert dans la requête de mise à jour (traduction en 2 requêtes de la précédente)

    La seule solution semble être de passer par une table intermédiaire, ce que j'aimerai éviter.

    J'ai beau relire les messages d'erreurs je ne vois pas ce qu'ils signifient et d'où vient le problème.
    Encore une fois ça ne me parait pas extraordinaire comme fonctionnalité, il doit bien y avoir un moyen prévu en SQL

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 949
    Points : 5 848
    Points
    5 848
    Par défaut
    Salut,
    Citation Envoyé par UVB_PC Voir le message
    Sur les forums on trouve des conseils du genre :
    UPDATE a SET a.Total = (select sum(b.Valeur) from b where a.Clef = b.Clef_A);

    Qui ne donnent pas de satisfaction (sur les forums)
    Ah bon?
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    SQL> select * from table_b;
     
          FK_A     VALEUR
    ---------- ----------
             1          5
             1          8
             1          4
             3          8
             3         95
             3         91
     
    6 ligne(s) sélectionnée(s).
     
    SQL> select * from table_a;
     
          ID_A      TOTAL
    ---------- ----------
             1
             2
             3
     
    SQL> UPDATE table_a a SET a.total = (select sum(b.Valeur) from table_b b where b.fk_a=a.id_a);
     
    3 ligne(s) mise(s) à jour.
     
    SQL> select * from table_a;
     
          ID_A      TOTAL
    ---------- ----------
             1         17
             2
             3        194
    Moi je suis plutôt satisfait

    Après je ne connais pas access, mais as tu une contrainte NOT NULL sur la colonne total (je pense que le message d'erreur serait différent, mais il est déjà tellement peu explicite )

    Si c'est le cas essaie comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE table_a a SET a.total = (select sum(b.Valeur) from table_b b where b.fk_a=a.id_a)
    where exists (select 1 from table_b b where b.fk_a=a.id_a);

  3. #3
    Nouveau membre du Club

    Inscrit en
    Octobre 2007
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 33
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par skuatamad Voir le message

    Après je ne connais pas access, mais as tu une contrainte NOT NULL sur la colonne total (je pense que le message d'erreur serait différent, mais il est déjà tellement peu explicite )
    Non, je n'ai pas cette contrainte (j'ai construit l'exemple pour simplifier,explorer le problème et le poster ici, le cas réel dispose de deux jointures)

    J'ai quand même essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE a SET a.total = (SELECT sum(b.Valeur) FROM b WHERE b.Clef_a=a.Clef)
    WHERE EXISTS (SELECT 1 FROM b WHERE b.Clef_a=a.clef);
    et j'ai toujours le message d'erreur :
    L'opération doit utiliser une requête qui peut être mise à jour

  4. #4
    Nouveau membre du Club

    Inscrit en
    Octobre 2007
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 33
    Points : 36
    Points
    36
    Par défaut
    Ca y'est j'ai trouvé la solution :
    ici
    Just to re-iterate... no part of an update query may be non-updateable. That includes subqueries.
    You can't get around it be using separate queries as a source.
    Jet is fully capable of optimizing by walking up the query tree - and it knows that the data isn't updateable.

    Any aggregate query will be non updateable.
    Functions are your salvation...
    e.g. instead of

    UPDATE TableName SET FieldName = (SELECT Sum(ValueField) FROM OtherTable)
    you need
    UPDATE TableName SET FieldName = DSum("ValueField", "OtherTable")
    or
    UPDATE TableName SET FieldName = fFunctionWhichDoesIt
    Ce qui donne dans mon exemple :
    UPDATE a SET a.total = Dsum("Valeur","b",a.Clef & "=b.Clef_A")

    Si on le fait via l'interface graphique, il suffit d'ajouter la table a et de mettre dans la partie mise à jour du champ Total: SomDom("Valeur";"b";a.Clef & "=b.Clef_A")

    C'est loin d'être élégant (dans la vrai vie ma condition est nettement plus complexe que la jointure ) mais ça a l'air de fonctionner

    Merci, savoir que la requête fonctionnait sur certains systèmes m'a permis d'affiner mes recherches.

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 949
    Points : 5 848
    Points
    5 848
    Par défaut
    Merci à toi d'avoir posté la solution

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

Discussions similaires

  1. Plusieurs SUM et jointure.
    Par TangoZoulou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/09/2007, 15h38
  2. Update sur une jointure
    Par nellynew dans le forum Langage SQL
    Réponses: 5
    Dernier message: 25/01/2007, 17h56
  3. UPDATE multiple avec jointure
    Par PyRoFlo dans le forum Requêtes
    Réponses: 6
    Dernier message: 25/05/2006, 15h56
  4. Update + SUM() ?
    Par dark_vidor dans le forum Langage SQL
    Réponses: 6
    Dernier message: 03/01/2006, 22h51
  5. Delete avec jointure impossible
    Par _developpeur_ dans le forum Access
    Réponses: 13
    Dernier message: 18/11/2005, 16h22

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