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 :

Calcul d'un total global et de sous total


Sujet :

Langage SQL

  1. #1
    Membre averti Avatar de LhIaScZkTer
    Inscrit en
    Mai 2004
    Messages
    564
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2004
    Messages : 564
    Points : 301
    Points
    301
    Par défaut Calcul d'un total global et de sous total
    Bonjour à tous,

    C'est un vendredi assez spécial pour moi ... Un de ces vendredi ou on arrive pas à ce sortir la tête du coussin tout en étant au boulot (heureusement c'est vendredi !!)

    Imaginons la table Panier avec les colonnes suivantes : quantite_pull, prix_pull, quantite_pantalon, prix_pantalon, quantite_chaussure, prix_chaussure

    Je désire effectuer le montant global pour chaque produit et par panier donc je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT (quantite_pull * prix_pull) as total_pull, (quantite_pantalon *prix_pantalon) as total_pantalon, (quantite_chaussure * prix_chaussure) as total_chaussure
    FROM Panier
    Si j'avais voulu prendre un panier en particulier je l'aurais ajouté dans la close WHERE avec on ID

    Maintenant j'aimerais calculer le total de chaque panier avec le total de chaque produit, je fais donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT (quantite_pull * prix_pull) as total_pull, (quantite_pantalon *prix_pantalon) as total_pantalon, (quantite_chaussure * prix_chaussure) as total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) as total_panier
    FROM Panier
    Avec toujours la clause WHERE si j'ai besoin de filtrer les paniers.

    Maintenant je désire calculer le montant global de plusieurs paniers donc je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) as montant_global
    FROM Panier
    -- Mais pour les paniers 1, 2, 3
    WHERE ID =1 OR ID =2 OR ID = 3
    Pour finir, et c'est là mon problème, comment coupler la requête 2 et 3.

    Je ne sais pas si j'ai été assez claire

    Merci pour votre aide

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    c'est un peu l'accouplement de la carpe et du lapin : ta requête 2 renvoie un tuple par panier, ta requête 3 renvoie un tuple pour un ensemble de panier (quelle est la règle de constitution de cet ensemble ?), je vois difficilement comment concilier les deux...

  3. #3
    Membre averti Avatar de LhIaScZkTer
    Inscrit en
    Mai 2004
    Messages
    564
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2004
    Messages : 564
    Points : 301
    Points
    301
    Par défaut
    Salut GrandFather et merci pour ton aide

    C'est bien ça mon problème, j'aurais aimé récupérer montant_global même si celui-ci est dupliqué à chaque ligne. Côté programmation je l'ai fais sans souci en C# ... mais le problème c'est que je dois générer un rapport Crystal et comme j'y comprend rien, je me suis dis que si je dupliquait montant_global ce serait super simple à récupérer

  4. #4
    Candidat au Club
    Inscrit en
    Août 2008
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Salut,

    Et si tu fesait un GROUP BY sur tes ID au lieu d'un WHERE.
    A tester, ça peut peut être marcher

    A+

  5. #5
    Membre averti Avatar de LhIaScZkTer
    Inscrit en
    Mai 2004
    Messages
    564
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2004
    Messages : 564
    Points : 301
    Points
    301
    Par défaut
    Salut cracozore merci pour ton aide,

    J'ai testé, mais le problème est qu'il veut toutes les colonnes qui sont utilisées dans le sum dans le group by

    En gros, voici la requête en l'état actuel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT (quantite_pull * prix_pull) AS total_pull, (quantite_pantalon *prix_pantalon) AS total_pantalon, (quantite_chaussure * prix_chaussure) AS total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier,
    (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) AS montant_global
    FROM Panier
    WHERE id IN(1,2,3)
    GROUP BY quantite_pull, prix_pull, quantite_pantalon, prix_pantalon, quantite_chaussure, prix_chaussure
    J'aimerais bien comprendre ce que je suis entrain de confondre, car je sais que se que je veux faire n'est pas juste ...

  6. #6
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par LhIaScZkTer Voir le message
    J'aimerais bien comprendre ce que je suis entrain de confondre, car je sais que se que je veux faire n'est pas juste ...
    Tu es en train de confondre la notion de groupe (GROUP BY) avec celle de sélection d'un ensemble de panier par leur ID.

    SUM() est une fonction d'aggrégat qui opère sur les tuples de chacun des groupes de tuples constitués par la commande GROUP BY. Quand il n'y a pas de commande GROUP BY, SUM() prend en compte tous les tuples de la table moins ceux filtrés par la clause WHERE, évidemment. Ton souci est qu'il n'y pas de groupement possible qui coïncide avec une sélection arbitraire de 3 paniers.

    Pour obtenir ce que tu veux, tu dois procéder en deux temps :
    • Ne sélectionner que les paniers 1, 2 et 3
    • Faire les calculs sur cette sélection

    Grâce aux requêtes imbriquées, cela peut être fait avec une seule requête SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT (quantite_pull * prix_pull) AS total_pull, (quantite_pantalon *prix_pantalon) AS total_pantalon, (quantite_chaussure * prix_chaussure) AS total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier,
    (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) AS montant_global
    FROM (SELECT * FROM Panier WHERE id IN(1,2,3)) AS P2
    P.S. : ...mais le mieux serait quand même de maîtriser les fonctions d'aggrégats disponibles dans Crystal Reports.

  7. #7
    Membre averti Avatar de LhIaScZkTer
    Inscrit en
    Mai 2004
    Messages
    564
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2004
    Messages : 564
    Points : 301
    Points
    301
    Par défaut
    Merci de ta patience GrandFather,

    Citation Envoyé par GrandFather Voir le message
    Pour obtenir ce que tu veux, tu dois procéder en deux temps :
    • Ne sélectionner que les paniers 1, 2 et 3
    • Faire les calculs sur cette sélection

    Grâce aux requêtes imbriquées, cela peut être fait avec une seule requête SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT (quantite_pull * prix_pull) AS total_pull, (quantite_pantalon *prix_pantalon) AS total_pantalon, (quantite_chaussure * prix_chaussure) AS total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier,
    (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) AS montant_global
    FROM (SELECT * FROM Panier WHERE id IN(1,2,3)) AS P2
    Pardonne mon ignorance, mais je n'avais jamais vu une tel requête. J'avais pensé à imbriquer les requêtes mais apparemment pas comme toi

    J'avais essayé de faire une auto jointure pour essayer de berner le SGBD mais ça ne marche pas non plus, c'est dommage car cette fausse bonne idée me plaisait bien

    Enfait, j'aurais aimé que montant_global se comporte comme si je faisais un cross join... C'est totalement débile, mais ça m'éviterais un grosse tracasserie avec Crystal Report que j'aime pas du tout, et en plus avec l'outil que j'ai développé par dessus pour faire des raports dynamique c'est encore pire, une vrai usine à gaz...
    Il me faut une bonne feinte

    Bon week-end.

  8. #8
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Après mûre réflexion, j'ai comme un doute sur la nécessité de la requête imbriquée... As-tu essayé tout simplement ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT (quantite_pull * prix_pull) AS total_pull, (quantite_pantalon *prix_pantalon) AS total_pantalon, (quantite_chaussure * prix_chaussure) AS total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier,
    (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) AS montant_global
    FROM panier
    WHERE id IN(1,2,3)

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Salut,

    Peut être qu'un SELECT dans SELECT est la feinte que tu recherches pour obtenir montant_global dupliqué dans chaque ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT (quantite_pull * prix_pull) AS total_pull, 
    		 (quantite_pantalon *prix_pantalon) AS total_pantalon, 
    		 (quantite_chaussure * prix_chaussure) AS total_chaussure,
     		 ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier,
    		 (SELECT (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) 
    		  FROM Panier WHERE id in (1,2,3)) as montant_global
    FROM Panier
    WHERE id in (1,2,3)
    Note la correspondance entre les 2 clauses WHERE.
    Le select dans le select te permet d'éviter le group by, par contre j'espère que t'as pas des millions de lignes parce qu'à mon avis les perfs vont être désastreuses.
    Sinon regarde du côté des fonctions analytiques.

    J'ai testé, mais le problème est qu'il veut toutes les colonnes qui sont utilisées dans le sum dans le group by
    Non il veut toutes les colonnes présentes dans le SELECT et pas dans le sum.

  10. #10
    Membre éclairé Avatar de Z3phur
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2007
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2007
    Messages : 680
    Points : 807
    Points
    807
    Par défaut
    salut, essaies donc ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select tmp1.id, tmp1.total_pull, tmp1.total_pantalon, tmp1.total_chaussure, tmp2.montant_global
    from
         (SELECT id, (quantite_pull * prix_pull) AS total_pull, (quantite_pantalon *prix_pantalon) AS total_pantalon, (quantite_chaussure * prix_chaussure) AS total_chaussure,
     ((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure) AS total_panier
    FROM Panier) tmp1,
         (SELECT (SUM((quantite_pull * prix_pull) + (quantite_pantalon *prix_pantalon) + (quantite_chaussure * prix_chaussure))) AS montant_global,id
    FROM Panier
    -- Mais pour les paniers 1, 2, 3
    WHERE ID =1 OR ID =2 OR ID = 3
    group by id) tmp2
    where tmp1.id = tmp2.id
    Tiens moi au courant si cela fonctionne...

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 862
    Points : 53 015
    Points
    53 015
    Billets dans le blog
    6
    Par défaut
    Votre modèle de données étant nullissime, vous aurez du mal à concevoir vos requêtes et les performances seront catastophique.
    En effet les colonnes :
    quantite_pull, prix_pull,
    quantite_pantalon, prix_pantalon,
    quantite_chaussure, prix_chaussure

    Sont redondantes.

    Votre table devrait être modélisée de la sorte :
    quantite, prix, nature
    la colonne nature devant contenir "pull", "chaussure", "pantalon" ou tout autre chose !

    Dès lors vos requêtes vont devenir triviales :

    -- Total par produit pour un panier (33) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT nature, SUM(prix * quantite) AS TOTAL
    FROM   Panier
    WHERE  panierID = 33
    GROUP  BY nature
    -- Total par produit et par panier pour tous les paniers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT panierID, nature, SUM(prix * quantite) AS TOTAL
    FROM   Panier
    GROUP  BY panierID, nature
    -- Total par produit et par panier pour certains paniers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT panierID, nature, SUM(prix * quantite) AS TOTAL
    FROM   Panier
    WHERE  PanierID IN (33, 25, 159)
    GROUP  BY panierID, nature
    -- Total par panier tout produits confondus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT panierID, SUM(prix * quantite) AS TOTAL
    FROM   Panier
    GROUP  BY panierID
    -- Total par produit pour un panier (33) et total global du panier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT nature, SUM(prix * quantite) AS TOTAL_NATURE
           (SELECT SUM(prix * quantite)
            FROM   Panier Pin
            WHERE  Pin.PanierID = Pout.PanierID) AS TOTAL_GLOBAL
    FROM   Panier Pout
    WHERE  panierID = 33
    GROUP  BY nature
    CONCLUSION : commencez par apprendre à modéliser correctement vos bases de données, cela vous aidera à faire des requêtes plus simples et plus performantes...

    A +

  12. #12
    Membre averti Avatar de LhIaScZkTer
    Inscrit en
    Mai 2004
    Messages
    564
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2004
    Messages : 564
    Points : 301
    Points
    301
    Par défaut
    Salut à tous,

    Désolé de ne pas avoir donné de nouvelles avant... mais les aléa des projets font que j'ai été assez occupé

    Pour répondre à Z3phur, non elle ne marche pas, après quelque correction cela ne me ramène pas le résultat attendu.

    Par contre skuatamad, ta requête retourne exactement le résultat que je recherchais !!!

    Enfin SQLpro, merci beaucoup pour tes précisions. A la base ma base de données ne traite pas du tout d'article ni de panier, mais afin de faciliter la compréhension j'en ai ressorti ce petit exemple simple(simpliste), qui permettait une compréhension assez aisé. Merci pour tes livres si bien écrit toujours un régal


    Merci à tous pour votre aide.

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

Discussions similaires

  1. [2012] Pourcentage d'un sous-total 1 sur un sous-total 2
    Par Ornitho76 dans le forum SSAS
    Réponses: 9
    Dernier message: 24/09/2014, 10h53
  2. Calculer le sous total dans un wwdbgrid
    Par BYALI dans le forum Composants VCL
    Réponses: 0
    Dernier message: 30/07/2008, 16h34
  3. [Champ, Agrégation] Calcul de sous-total
    Par CIFQ_Drew dans le forum iReport
    Réponses: 1
    Dernier message: 20/05/2008, 22h26
  4. calcul de sous total dans un etat
    Par qltmi dans le forum IHM
    Réponses: 1
    Dernier message: 11/06/2007, 06h55
  5. Réponses: 2
    Dernier message: 28/09/2005, 17h08

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