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

Bases de données Delphi Discussion :

Pb SQL dans un ADOQuery pour SUM d'une colonne selon valeur d'un autre champ


Sujet :

Bases de données Delphi

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 4
    Points : 0
    Points
    0
    Par défaut Pb SQL dans un ADOQuery pour SUM d'une colonne selon valeur d'un autre champ
    Bonjour,

    impossible de résoudre cette requête SQL.
    J'ai 2 tables ADO (access) en maitre - détail
    1 table commande liée avec le champ Commande_No à la table ci dessous
    1 table details

    Je souhaite calculer la sum d"un champ prix_unitaire de la table detail, seulement quand les champs Commande_No des 2 tables sont identiques.
    Voila mon SQL

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT SUM(prix_unitaire)
    FROM DETAILS,COMMANDES
    WHERE DETAILS.Commande_No=COMMANDES.Commande_No
    rien ne se passe...
    merci pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    tu devrais l'écrire comme ci avec INNER JOIN
    tu veux combien de ligne de résultat ?

    1 seule ligne, donc le total de TOUTES les commandes
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT SUM(prix_unitaire)
    FROM COMMANDES
    INNER JOIN DETAILS ON DETAILS.Commande_No=COMMANDES.Commande_No

    1 ligne par commande, chacune ayant le total d'une commande, le nombre de ligne dépend de la table COMMANDES
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT COMMANDES.Commande_No, SUM(prix_unitaire)
    FROM COMMANDES
    INNER JOIN DETAILS ON DETAILS.Commande_No=COMMANDES.Commande_No
    GROUP BY COMMANDES.Commande_No

    Enfin, si il existe des Commande_No dans DETAILS mais pas dans COMMANDES, il y a un probléme de modélisation !
    Soit il manque un DELETE CASCADE pour effacer le Détail d'une Commande
    Soit il manque une CONSTRAINTS pour empêcher l’effacement d'une Commande contenant encore des Détails !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 4
    Points : 0
    Points
    0
    Par défaut
    Merci pour ta réponse ShaiLeTroll

    En fait le résultat n'est pas conditionné, il me donne toute la table détails
    Je refais un point avec un exemple
    Table COMMANDES : Command_No ; Date de com ; Total ; remarques
    ;1;12/12/12;18;qsdfqsd
    ;3;13/01/02;1.25;sdfsdfdf
    ;4;02/02/01;2;qsqsqs
    Table DETAIL : Details_No; Command_No ; Quantité ; Produit ; Prix_Unitaire
    ;1;1;5;AK12;12.50;
    ;2;1;6;AK45;5.50;
    ;3;3;10;AK42;1.25;
    ;4;4;2;AK11;2;
    .....
    Ces 2 tables sont liés en maitre détails par Command_No
    En fait quand je suis sur le DBGRID des commandes par exemple sur la commande 1 mon DBGRID detail m'affiche donc 2 détails.
    Je souhaite la somme de 12.5+5.5 soit 18, le top serai meme qu’il me l’ajoute au total dans la table Commande (car je le mets à la main le 18 !)
    Si j’ajoute ensuite un nouveau détail sur une commande, il faudrait que le total de cette commande se mette à jour.
    En tout cas le code SQL me donne le total de la table détails soit 21.25 !
    On dirait que le « ON » n’est pas pris en compte.

    Je galère.
    Merci.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Ce n'est pas INNER JOIN ... ON qui pose problème, c'est le manque de GROUP BY !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Commande_No, SUM(prix_unitaire) as Px, SUM(Quantité * Prix_Unitaire) as Total
    FROM DETAILS
    GROUP BY Commande_No
    donnera
    Code set : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1	18	95.5
    3	1.25	10.25
    4	2	4

    Tu peux mettre un TRIGGER pour que la table COMMANDES soit mis à jour à chaque modification de DETAILS, mais ça c'est quand tu maitriseras mieux le SQL
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Ce qui est très original c'est la somme de prix unitaire , celle là on ne me l'avais jamais faite
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Nouveau Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 4
    Points : 0
    Points
    0
    Par défaut
    Merci ShaiLeTroll pour toutes ces infos (le lien SQL est remarquable)


    Mais ca ne fonctionne pas.
    En fait pour arriver à trouver mon 18 par exemple
    En faisant ce qui suit ca marche

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT SUM(Prix_Unitaire)
    FROM DETAILS
    WHERE DETAILS.commande_No=1
    (il va bien chercher les 2 détails de la commande N° 1 soir 12.5+5.5)

    Mais si je fais ce qui suit pour être on va dire en dynamique cela ne marche pas
    WHERE DETAILS.commande_No=COMMANDES.Commandes_No
    message erreur : le paramètre Commandes.commande_No n'a pas de valeur par defaut.

    et si je modifie mon FROM ci dessous il me sort le total de toutes les lignes details soit 21.25 et la retour à la case depart !
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT SUM(Prix_Unitaire)
    FROM DETAILS, COMMANDES
    WHERE DETAILS.commande_No=COMMANDES.Commandes_No

    ca ma l'air pourtant simple mais il y a un truc qui m'échappe.
    merci

  7. #7
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par vincevb3 Voir le message
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT SUM(Prix_Unitaire)
    FROM DETAILS
    WHERE DETAILS.commande_No=1
    (il va bien chercher les 2 détails de la commande N° 1 soir 12.5+5.5)

    Mais si je fais ce qui suit pour être on va dire en dynamique cela ne marche pas
    WHERE DETAILS.commande_No=COMMANDES.Commandes_No
    message erreur : le paramètre Commandes.commande_No n'a pas de valeur par defaut.
    C'est normal que cela ne fonctionne pas, tu n'as plus la table commande dans le FROM donc où veux tu que le moteur de base de données cherche les informations !!!

    Citation Envoyé par vincevb3 Voir le message
    et si je modifie mon FROM ci dessous il me sort le total de toutes les lignes details soit 21.25 et la retour à la case depart !
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT SUM(Prix_Unitaire)
    FROM DETAILS, COMMANDES
    WHERE DETAILS.commande_No=COMMANDES.Commandes_No

    ca ma l'air pourtant simple mais il y a un truc qui m'échappe.
    merci
    Si tu veux la somme des prix unitaires (comme dit Sergiomaster ) par commandes il te faut faire comme te le montre Shailetroll plus haut (en enlevant la quantité de la somme).

    Sinon tu peux consulter la rubrique SQL du site.
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par vincevb3 Voir le message
    ca ma l'air pourtant simple mais il y a un truc qui m'échappe.


    J'ai l'impression de me répéter !

    Citation Envoyé par ShaiLeTroll Voir le message
    Ce n'est pas INNER JOIN ... ON qui pose problème, c'est le manque de GROUP BY !

    Utilise CE SQL
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Commande_No, SUM(prix_unitaire) as Px, SUM(Quantité * Prix_Unitaire) as Total
    FROM DETAILS
    GROUP BY Commande_No
    ou celui-ci
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT COMMANDES.Commande_No, SUM(DETAILS.prix_unitaire) as Px, SUM(DETAILS.Quantité * DETAILS.Prix_Unitaire) as Total
    FROM COMMANDES
    INNER JOIN DETAILS ON DETAILS.Commande_No=COMMANDES.Commande_No
    GROUP BY COMMANDES.Commande_No



    Edit :
    Pour "Quantité", le é pourrait poser problème, je te laisse trouver au besoin les caractères d'échappement pour les noms de colonnes
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Nouveau Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 4
    Points : 0
    Points
    0
    Par défaut
    merci pour vos réponses,
    je vais faire le test ce soir, mais je souhaite 1 seul résultat TOTAL.
    Mais avec un SELECT avec plusieurs champs je vois pas trop ...

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par vincevb3 Voir le message
    merci pour vos réponses,
    je vais faire le test ce soir, mais je souhaite 1 seul résultat TOTAL.
    Mais avec un SELECT avec plusieurs champs je vois pas trop ...
    J'anticipe depuis le début que 18 est faux car dans le total d'une commande, on additionne pas juste le prix, il faut gérer les quantités, je ne suis pas le seul à avoir anticipé cette erreur !



    Citation Envoyé par vincevb3 Voir le message
    pour être on va dire en dynamique cela ne marche pas
    A mon avis, tu as mal expliqué ton problème, ton SELECT SUM, il te sert à quoi ?
    le "dynamique" ne me dit pas que c'est juste passer 1, 3 ou 4 via un Paramètre (voir ADOQuery.Parameters.ParamByName) ?

    Ton but est-il de l'affecter à COMMANDES ?

    utilise DSum dans ton UPDATE

    Directement dans ACCESS (j'ignore si le ADOQuery l'autorise)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE COMMANDES 
    SET COMMANDES.Total = DSum("[prix_unitaire]","DETAILS","Commandes_No=""" & [Commandes_No] & """");

    A tester "[Quantité * prix_unitaire]" au lieu de "[prix_unitaire]".

    Tu utilises ACCESS, c'est très limité comme SQL, je ne pense pas qu'il supporte ceci
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    UPDATE COMMANDES as C
    SET C.Total = (
      SELECT SUM(DETAILS.prix_unitaire) 
      FROM DETAILS as D 
      WHERE D.commande_No = C.Commandes_No
    )
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Réponses: 38
    Dernier message: 08/11/2013, 12h12
  2. Réponses: 13
    Dernier message: 30/11/2010, 17h31
  3. Syntaxe requête SQL dans JCL MVS pour lire sous AIX
    Par Claire de Morsang dans le forum DB2
    Réponses: 2
    Dernier message: 18/03/2008, 17h14
  4. Réponses: 2
    Dernier message: 31/01/2007, 09h49
  5. Instruction SQL dans un bouton pour filtrer info formulaire
    Par beegees dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 05/09/2005, 13h26

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