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 MySQL Discussion :

2 tables, une somme, une soustraction, un problème


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut 2 tables, une somme, une soustraction, un problème
    Hello,

    je suis en galère avec une petite requête d'apparence toute simple mais qui me pourrit la vie sans que j'arrive à la décoincer.

    Je dispose d'une table facture et d'une table règlement composées de la façons suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    tb_Facture
    CleFacture
    LibelleFacture
    MontantFacture
     
    tb_Reglement
    CleReglement
    CleFacture_foreign
    MontantReglement
    MontantActif // permet de dire si on prend en compte le règlement ou pas
    Evidemment, je peux avoir plusieurs règlements pour une même facture

    Mon but est, en une seule requête, d'afficher, pour chaque facture :
    1. le libellé de la facture,
    2. le montant de la facture,
    3. la somme des règlements
    4. le montant restant à régler

    J'ai donc écrit la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT
    	  f.CleFacture
    	, f.LibelleFacture
    	, f.MontantFacture
    	, CASE WHEN r.MontantActif > 0 THEN sum(r.MontantReglement) ELSE 0 END as montantRegle
    	, CASE WHEN r.MontantActif > 0 THEN f.MontantFacture - sum(r.MontantReglement) ELSE f.MontantFacture END as montantRestant
    FROM 
    	tb_Facture f LET JOIN
    	tb_Reglement r ON f.CleFacture = r.CleFacture_foreign
    GROUP BY
    	f.CleFacture
    Le montant réglé semble correctement facturé.
    Le souci est qu'en fonction de la valeur du premier MontantActif rencontré, la somme des règlements est (ou pas si MontantActif = 0) déduite du montant Total et du coup, mon montantRestant est faux...

    Auriez-vous une idée me permettant de résoudre mon souci ?

    Merci de votre aide !

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    bonjour,


    Appliquez la règle de base des group by et vous n'aurez pas ce genre de problème (MySql...)

    Toute colonne présente dans le select non encadrée par une fonction d'agrégation doit être présente dans le group by.

    Du coup là y a plein de problème !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT
    	  f.CleFacture
    	, f.LibelleFacture
    	, f.MontantFacture
    	, sum(CASE WHEN r.MontantActif > 0 THEN r.MontantReglement ELSE 0 END) AS montantRegle
    	, f.MontantFacture - coalesce(sum(CASE WHEN r.MontantActif > 0 THEN r.MontantReglement ELSE 0 END), 0) AS montantRestant
    FROM 
    	tb_Facture f LET JOIN
    	tb_Reglement r ON f.CleFacture = r.CleFacture_foreign
    GROUP BY
    	f.CleFacture, f.LibelleFacture, f.MontantFacture

  3. #3
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut
    Merci de ta réponse, malheureusement, le problème ne semble pas venir de là...

    Ma requête est un poil plus compliqué, mais, j'ai repris ton principe de calcul et complété le group by. Toutefois, la valeur de la première ligne de règlement rencontrée défini les autres...

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
     
    select 
    	`facture`.`FACTU_Pkey` AS `FACTU_Pkey`,
    	`facture`.`FACTU_Statut` AS `FACTU_Statut`,
    	`facture`.`FACTU_Numero` AS `FACTU_Numero`,
    	`facture`.`FACTU_DateCreation` AS `FACTU_DateCreation`,
    	`facture`.`FACTU_Document` AS `FACTU_Document`,
    	`facture`.`FACTU_MontantTotal` AS `FACTU_MontantTotal`,
    	`facture`.`FACTU_MontantTotalTTC` AS `FACTU_MontantTotalTTC`,
    	`utilisateur`.`UTILI_Login` AS `UTILI_Login`,
    	`client`.`CLIE_Nom` AS `CLIE_Nom`,
    	`modele`.`MODEL_Libelle` AS `MODEL_Libelle`,
    	`typefacture`.`TYPFAC_Typedoc` AS `TYPFAC_Typedoc`,
    	`facture`.`DOMAIN_Pkey` AS `DOMAIN_Pkey`,
    	`facture`.`FACTU_NomDocFinal` AS `FACTU_NomDocFinal`,
    	(case 
    		when 
    			isnull(cast(sum(`reglement`.`REGLE_Montant`) as decimal(10,0))) OR 
    			`reglement`.`REGLE_Active` = 0 OR 
    			isnull(cast(sum(`reglement`.`REGLE_Active`) as decimal(10,0))) 
    		then 
    			0 
    		else 
    			sum(`reglement`.`REGLE_Montant`) end
    	) AS `calcMontantRegle`,
     
    	`facture`.`FACTU_MontantTotalTTC` - coalesce(sum(CASE WHEN coalesce(REGLE_Active, 0) > 0 THEN coalesce(REGLE_Montant, 0) ELSE 0 END), 0) AS `calcMontantRestant`
     
    from 
    	(((((`facture` join 
    	`typefacture` on((`facture`.`TYPFAC_Pkey` = `typefacture`.`TYPFAC_Pkey`))) left join 
    	`reglement` on((`facture`.`FACTU_Pkey` = `reglement`.`FACTU_Pkey`))) join 
    	`client` on((`facture`.`CLIE_Pkey` = `client`.`CLIE_Pkey`))) join 
    	`utilisateur` on((`facture`.`UTILI_Pkey` = `utilisateur`.`UTILI_Pkey`))) join 
    	`modele` on((`facture`.`MODEL_Pkey` = `modele`.`MODEL_Pkey`))) 
    where 
    	(`facture`.`FACTU_Statut` = 1) and 
    	(`typefacture`.`TYPFAC_Typedoc` in (1,3)) 
    group by 
    	  `facture`.`FACTU_Pkey`
    	, `facture`.`FACTU_Statut`
    	, `facture`.`FACTU_Numero`
    	, `facture`.`FACTU_DateCreation`
    	, `facture`.`FACTU_Document`
    	, `facture`.`FACTU_MontantTotal`
    	, `facture`.`FACTU_MontantTotalTTC`
    	, `utilisateur`.`UTILI_Login`
    	, `client`.`CLIE_Nom`
    	, `modele`.`MODEL_Libelle`
    	, `typefacture`.`TYPFAC_Typedoc`
    	, `facture`.`DOMAIN_Pkey`
    	, `facture`.`FACTU_NomDocFinal`;

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    Bonjour,

    Est-ce que cette version simplifiée de la requête donne le bon résultat ?
    (au passage les parenthèses a profusions ne servent pas à grand chose, et j'ai des doutes sur vos conditions dans les case / when)

    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
     
    SELECT 
    	facture.FACTU_Pkey AS FACTU_Pkey,
    	facture.FACTU_Numero AS FACTU_Numero,
    	facture.FACTU_MontantTotalTTC AS FACTU_MontantTotalTTC,
    	coalesce(sum(reglement.REGLE_Montant), 0) AS calcMontantRegle,
    	facture.FACTU_MontantTotalTTC - coalesce(sum(REGLE_Montant), 0) AS calcMontantRestant
    FROM 
    	facture JOIN 
    	typefacture ON facture.TYPFAC_Pkey = typefacture.TYPFAC_Pkey 
    	LEFT JOIN reglement ON facture.FACTU_Pkey = reglement.FACTU_Pkey and reglement.REGLE_Active > 0
    WHERE 
    	facture.FACTU_Statut = 1 AND 
    	typefacture.TYPFAC_Typedoc IN (1,3) 
    GROUP BY 
    	  facture.FACTU_Pkey
    	, facture.FACTU_Numero
    	, facture.FACTU_MontantTotalTTC;
    Si, non, pouvez vous joindre un jeu de donnée d'un cas ?

  5. #5
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut
    Oui, ça fonctionne !

    Je pense que c'est parce que je tente de récupérer les règlements même si ils ne sont pas activés, ce qui n'a pas franchement d'intérêt.

    merci !

    concernant les parenthèses, il semble que ce soit mysql qui les a ajouté à la création de la vue... mais je suis d'accord que ça n'aide pas forcément à la lisibilité.

    encore merci !

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 27/02/2021, 16h57
  2. [AC-2007] transferer une table en d'une base à une autre depuis la frontale
    Par samloba dans le forum VBA Access
    Réponses: 1
    Dernier message: 01/12/2010, 10h41
  3. remplir 2 tables dont l'une prends une clé etrangere.
    Par eddycool dans le forum Langage
    Réponses: 3
    Dernier message: 06/05/2009, 19h41
  4. [XL-2007] Ajouter une somme à une cellule déja remplie
    Par charline33 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 30/04/2009, 14h10
  5. Update d'une table avec d'une base à une autre
    Par bb44115 dans le forum SQL
    Réponses: 1
    Dernier message: 28/05/2008, 16h52

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