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

Requêtes et SQL. Discussion :

Calcul produit regroupement [AC-2003]


Sujet :

Requêtes et SQL.

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut Calcul produit regroupement
    Bonjour,

    Dans une de mes requêtes, je souhaiterais calculer le produit de plusieurs valeurs à partir d'un regroupement (de la même façon qu'Access calcule la moyenne), y a t'il une expression pour ça?

    Merci d'avance

    Marie
    [débutante Access]

  2. #2
    Membre habitué Avatar de anouar_chaieb
    Inscrit en
    Mai 2004
    Messages
    276
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 276
    Points : 178
    Points
    178
    Par défaut
    Bonjour,
    Tu crées une deuxième requête et tu fais la multiplication des valeurs regroupées
    Quel est le plus rapide? lire le FAQ:

    http://access.developpez.com/faq/ Ou bien créer un post?

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Mais mon problème c'est bien ça, comment faire la multiplication??
    En fait j'ai 2 colonnes, A et B.
    Je veux regrouper à partir de A pour obtenir en valeur sur B le produit des valeurs regroupées (de B bien sûr). Et je ne connais pas l'écriture de l'instruction (je suis vraiment débutante sur les requêtes)

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    bonjour,

    on peut s'en sortir avec une astuce mathématique sur le log népérien ( ln(a)+ln(b) = ln(ab) )

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT 
    LaTable.A, 
    exp(sum(log(LaTable.B))) as Multipli
    FROM LaTable
    GROUP BY LaTable.A;

    mais attention aux dépassements de capacité.

  5. #5
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    D'accord.
    Mais ça je l'écriscomment dans ma requête?..... (vraiment débutante...)
    Parce que sortie de l'affichage avec les tables, j'ai un peu de mal...

  6. #6
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    Il faut basculer en "mode SQL" et dans la fenêtre vierge tu colles le code en adaptant les noms de tables&champs. Tu peux ensuite re-basculer en "mode création" pour voir comment Access l’interprète.

    Note que la fonction Log (logarithme népérien) est définie pour des valeurs de B appartenant à ]0,+∞[ (un peu de révisions pour les presque-futurs bacheliers qui vont débuter l’épreuve de Maths cette semaine).

  7. #7
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Bonjour,

    Alors là je me retrouve avec un message "Appel de procédure incorrect" quand j'essaye de repasser en mode création.
    En fait, je me suis basée sur la formule automatique créée avec un regroupement en Compte, et j'ai modifié le compte avec "exp(sum(log"

  8. #8
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    bonjour,

    je me retrouve avec un message "Appel de procédure incorrect"...
    sans doute que tu as des valeurs de B en dehors du domaine de définition de la fonction Logn.
    J'avais prévenu
    Citation Envoyé par f-leb
    Note que la fonction Log (logarithme népérien) est définie pour des valeurs de B appartenant à ]0,+∞[
    il va falloir créer ta propre fonction en VBA, du style:

    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
    Public Function multipli(champA As Variant) As Double
    Dim db As Database
    Dim rst As DAO.Recordset
    Dim strSQL As String
    Dim resultat As Double
     
    On Error GoTo err
    Set db = CurrentDb
    strSQL = "SELECT LaTable.B FROM LaTable WHERE LaTable.A='" & champA & "';"
    resultat = 1#
    ' si champA est numérique, il faut alors écrire:
    ' "SELECT LaTable.B FROM LaTable WHERE LaTable.A=" & champA
     
    Set rst = db.OpenRecordset(strSQL)
     
    If rst.EOF Then 'la requête ne renvoit aucun enregistrement
        Exit Function
    Else
        rst.MoveFirst
        While Not rst.EOF
            resultat = resultat * rst.Fields(0) 'calcul
            rst.MoveNext
        Wend
    End If
     
    multipli = resultat
    rst.Close
    Set rst = Nothing
     
    err:
    End Function
    fonction (rédigée très rapidement donc à tester) à copier/coller dans un module et à adapter selon tes noms de champs&tables.

    Puis dans une nouvelle requête:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT LaTable.A, multipli(LaTable.A) AS Multiplication
    FROM LaTable
    GROUP BY LaTable.A;

  9. #9
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Bonjour,

    Alors, j'ai lancé tout ça, ça fonctionne sans message d'erreur, mais le résultat n'est pas encore bon.
    Mes valeurs dans B sont comprises entre 0 et 1, avec 1 à 2 décimales (je ne sais pas si ça peut interférer...), et pour le moment ma colonne Multiplication ne donne que 0.00 (dans les propriétés, j'ai attribué un format Standard à 2 décimales).

    Par ailleurs, petit détail qui joue peut-être, A et B ne sont pas situés dans la même table (mais j'ajoute bien à chaque fois les INNER JOIN)

    Le temps d'exécution de la requêtes est toujours assez long.

  10. #10
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    Bonjour,
    Citation Envoyé par marie.l
    Mes valeurs dans B sont comprises entre 0 et 1, avec 1 à 2 décimales (je ne sais pas si ça peut interférer...), et pour le moment ma colonne Multiplication ne donne que 0.00 (dans les propriétés, j'ai attribué un format Standard à 2 décimales).
    0.1x0.1x0.1=0.001, avec deux décimales ça fait 0.00 ! Avec des nombres entres 0 et 1, la multiplication peut tendre rapidement vers 0, il faudrait au moins essayer avec plus de décimales ou avec un format nombre général…

    Citation Envoyé par marie.l
    Par ailleurs, petit détail qui joue peut-être, A et B ne sont pas situés dans la même table (mais j'ajoute bien à chaque fois les INNER JOIN)
    Eventuellement, poste le code SQL si le problème persiste.

    Citation Envoyé par marie.l
    Le temps d'exécution de la requêtes est toujours assez long.
    Assez long comment ? 5 secondes ? 10 minutes ?
    Donne-nous une idée de la volumétrie de tes données (nombres de lignes de chacune des deux tables en gros). Pour une valeur de A, combien de termes B à multiplier entre eux (en moyenne) ?

  11. #11
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Bon, autant pour moi, les maths sont loin. Mais le nombre de décimales ne change rien, je me retrouve quand même avec des 0 partout (nombre général, 7 décimales).

    A contient 600 lignes, B 2000. En moyenne, il y a 2 B pour 1 A, mais ça peut monter jusqu'à 10 B. Et c'est long, c'est à dire que ça dure 30 secondes (oui bon, c'est pas si long que ça d'accord...)


    Alors pour mon code, le SQL de la requête donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Risque_Correction_Poste.NumPosteSiteRisque, multipli(Risque_Correction_Poste.NumPosteSiteRisque) AS Multiplication, Count(Corr_Type.Valeur) AS CompteDeValeur
    FROM ((Corr_Type INNER JOIN Correction ON Corr_Type.TypeCorr = Correction.TypeCorr) INNER JOIN Risque_Correction ON Correction.NumCorr = Risque_Correction.NumCorr) INNER JOIN Risque_Correction_Poste ON Risque_Correction.NumRisqueCorr = Risque_Correction_Poste.NumRisqueCorr
    GROUP BY Risque_Correction_Poste.NumPosteSiteRisque;
    Et la fonction :

    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
    Public Function multipli(NumPosteSiteRisque As Variant) As Double
    Dim db As Database
    Dim rst As DAO.Recordset
    Dim strSQL As String
    Dim resultat As Double
     
    On Error GoTo err
    Set db = CurrentDb
    strSQL = "SELECT Corr_Type.Valeur FROM Corr_Type INNER JOIN Correction ON Corr_Type.TypeCorr = Correction.TypeCorr)INNER JOIN Risque_Correction ON Correction.NumCorr = Risque_Correction.NumCorr)INNER JOIN Risque_Correction_Poste ON Risque_Correction.NumRisqueCorr = Risque_Correction_Poste.NumRisqueCorr WHERE Risque_Correction_Poste.NumPosteSiteRisque='" & NumPosteSiteRisque
    resultat = 1#
    ' si champA est numérique, il faut alors écrire:
    ' "SELECT LaTable.B FROM LaTable WHERE LaTable.A=" & champA
     
    Set rst = db.OpenRecordset(strSQL)
     
    If rst.EOF Then 'la requête ne renvoit aucun enregistrement
        Exit Function
    Else
        rst.MoveFirst
        While Not rst.EOF
            resultat = resultat * rst.Fields(0) 'calcul
            rst.MoveNext
        Wend
    End If
     
    multipli = resultat
    rst.Close
    Set rst = Nothing
     
    err:
    End Function
    ... ça fait une bonne longueur.

  12. #12
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strSQL = "SELECT Corr_Type.Valeur FROM Corr_Type ... WHERE Risque_Correction_Poste.NumPosteSiteRisque='" & NumPosteSiteRisque
    Essaye en enlevant l'apostrophe en rouge...

    Si non, insère un debug.print (strSQL) dans le code VBA pour voir si la chaîne strSQL a une bonne tête.

  13. #13
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    L'apostrophe ne change rien.
    J'ai essayé d'insérer le Debug.Print mais soit je ne l'ai pas mis au bon endroit, soit ça n'a rien changé.
    Il y a quand même un truc qui me chifonne dans cette histoire. Si on reprend le code de la requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Risque_Correction_Poste.NumPosteSiteRisque, multipli(Risque_Correction_Poste.NumPosteSiteRisque) AS Multiplication
    FROM ((Corr_Type [...] ON Risque_Correction.NumRisqueCorr = Risque_Correction_Poste.NumRisqueCorr
    GROUP BY Risque_Correction_Poste.NumPosteSiteRisque;
    pourquoi est-ce qu'on applique multipli à mon champ A et pas au B?? On lui a demandé de le faire dans ce sens dans le VBA?


    ** Champ A = Risque_Correction_Poste.NumPosteSiteRisque
    ** Champ B = Corr_Type.Valeur

  14. #14
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    Tilt !
    Supprime temporairement le On error goto, tu devrais avoir un message d’erreur.

    Dans strSQL, je vois des parenthèses fermantes mais il manque les parenthèses ouvrantes.

    On va y arriver, on va y arriver

  15. #15
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Yahoo!
    On y est, c'est bien les parenthèses qui le perturbaient. En tout cas merci BEAUCOUP
    ET heu... je ne ferme pas encore la discussion, les valeurs là doivent me servir pour calculer un autre champ alors si par hasard ça ne fonctionne pas là, je te redemanderai .

  16. #16
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    ... ce que je vais faire tout de suite finalement, ça m'évitera un petit casse tête je crois.
    Donc je souhaiterais que le résultat de cette petite multiplication soit reporté dans une seconde requête où là mon champ A n'est pas (et ne doit pas être) regroupé, j'imagine (j'espère) que c'est simple, mais autant profiter de tes compétences!

  17. #17
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut
    Bonjour,

    Citation Envoyé par marie.l
    …que le résultat de cette petite multiplication soit reporté dans une seconde requête où là mon champ A n'est pas (et ne doit pas être) regroupé
    Avec ou sans GROUP BY, il suffit d’appeler la fonction avec le champ A comme paramètre dans le SELECT :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT LaTable.A, multipli(LaTable.A) AS Multiplication, AutreChamp
    FROM LaTable INNER JOIN AutreTable ONWHERE

    La requête de la function Multipli se charge de récupérer les champs B correspondants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strSQL = "SELECT LaTable.B FROM LaTable WHERE LaTable.A=" & champA
    Est-ce que le traitement prend toujours autant de temps ?
    Note que la fonction devrait peut-être prendre en compte des cas particuliers ou B=Null, B=0 …

  18. #18
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Bonjour,

    Alors, la simple transposition à ma requête a bien fonctionné, on avance bien!
    Et maintenant si je veux que mon champ B soit issu d'une valeur stockée dans la requête, je lui dis comment?

    Bon, si j'exagère tu me le dis hein...

  19. #19
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 621
    Points : 56 866
    Points
    56 866
    Billets dans le blog
    40
    Par défaut ??
    Citation Envoyé par marie.l Voir le message
    Et maintenant si je veux que mon champ B soit issu d'une valeur stockée dans la requête, je lui dis comment?
    Pas compris ce que tu veux, tu pourrais donner plus de détails avec un exemple pour illustrer ?

  20. #20
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Lol

    Bon, j'essaye de faire ça brièvement. Ma BDD me permet de faire le document unique d'évaluation des risques professionnels de mon entreprise.
    Le champ A est l'ID des différents risques relevés. Le champ B est la valeur attribuée aux différentes corrections possibles à mettre en place pour minimiser le risque, en fait c'est un coefficient réducteur de risque.
    Mais les corrections peuvent soit être appliquées actuellement, soit être simplement préconisées.
    Si les corrections sont appliquées, je veux que le coefficient réducteur soit appliqué tel quel.
    Par contre, si les corrections sont préconisées, je ne veux pas réduire le risque.

    J'ai donc créé un champ B' dans ma requête où les corrections préconisées ont toutes une valeur de 1 et où celles appliquées ont leur valeur réelle.

    Et je voudrais donc que le produit soit réalisé sur la base de B' et pas de B.

    Voilà, tu sais tout.

    Ca va mieux comme ça?

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

Discussions similaires

  1. [VxiR2] Calcul somme regroupée par région
    Par lolymeupy dans le forum Webi
    Réponses: 9
    Dernier message: 20/05/2015, 13h16
  2. [AC-2013] Champs calculé et regroupement Max
    Par guy2004 dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 07/02/2015, 12h48
  3. Import, calcul et regroupement.
    Par cyd77 dans le forum Général Python
    Réponses: 2
    Dernier message: 22/07/2011, 17h11
  4. calcul de regroupements?
    Par betauser dans le forum IHM
    Réponses: 2
    Dernier message: 02/02/2011, 09h12
  5. calcul de date sur un regroupement de champ en vb
    Par bazilus dans le forum Access
    Réponses: 1
    Dernier message: 06/10/2006, 13h29

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