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 :

Condition + SUM(DISTINCT(champ))


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mai 2008
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 382
    Points : 191
    Points
    191
    Par défaut Condition + SUM(DISTINCT(champ))
    Bonjour à tous,

    J'ai un problème avec le morceau de la requête suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(CASE WHEN od.id_achat_articles<>0 THEN DISTINCT(montant_total) ELSE od.debit END) AS depense
    Voici ma requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT od.date, COUNT(od.id) AS nombre, 
    SUM(CASE WHEN od.id_achat_articles<>0 THEN DISTINCT(od.montant_total) ELSE od.montant_total END) AS depense, 
    SUM(CASE WHEN od.id_type_paiement = 1 THEN od.debit ELSE 0 END) AS depense_liquide FROM operation_depenses od 
    LEFT JOIN achat_articles aa ON aa.id_achat=od.id_achat_articles
    WHERE (od.date BETWEEN '2011-07-20 01:31:01' AND '2011-08-25 23:00:00') 
    AND (CASE WHEN aa.id_filtre IS NULL THEN od.id_filtre ELSE aa.id_filtre END)=0
    Alors que ce morceau fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(DISTINCT(od.montant_total))
    Voici ma table:


    L'alias depense doit être égal à 66.53 (19.71+41.32+5.50).

    EDIT> En faite j'aimerais plutôt faire un DISTINCT(id_achat_articles) et calculer la somme de od.montant_total.

    Merci pour 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 : 41
    Localisation : France, Rhône (Rhône Alpes)

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


    Et où qu'il est le group by ?

    Sinon pourquoi avez-vous des doublons dans votre table d'opération bancaire ...?

  3. #3
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mai 2008
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 382
    Points : 191
    Points
    191
    Par défaut
    Merci punkoff pour ta réponse,

    le group by je l'utilise ensuite pour faire des tries par ans, mois, semaines, jours.

    Enfaite, je n'ai pas de doublon, c'est juste que je n'ai pas mis tous les champs.
    Car l'aperçu de la table c'est enfaite le résultat de la jointure.

    Je viens de mettre a jour la tableau ci-dessus obtenu avec la requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM operation_depenses od 
    LEFT JOIN achat_articles aa ON aa.id_achat=od.id_achat_articles
    WHERE (od.date BETWEEN '2011-07-20 01:31:01' AND '2011-08-25 23:00:00')
    J'ai voulu essayé de simplifier pour expliquer mon problème.

    Cela dit en cherchant plus profondement, j'ai trouvé quelquechose que ressemble:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(DISTINCT(CASE WHEN od.id_achat_articles<>0 THEN od.montant_total END))+SUM(CASE WHEN od.id_achat_articles=0 THEN od.montant_total END) AS depense
    Il va falloir que je vérifie l’exactitude des résultats.

    Cependant j'ai un problème de résultat avec le group by:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT od.date, COUNT(od.id) AS nombre, 
    SUM(DISTINCT(CASE WHEN od.id_achat_articles<>0 THEN od.montant_total END))+SUM(CASE WHEN od.id_achat_articles=0 THEN od.montant_total END) AS depense, 
    SUM(CASE WHEN od.id_type_paiement = 1 THEN od.debit ELSE 0 END) AS depense_liquide FROM operation_depenses od 
    LEFT JOIN achat_articles aa ON aa.id_achat=od.id_achat_articles
    WHERE (od.date BETWEEN '2011-01-26 01:31:01' AND '2012-01-26 23:00:00')
    GROUP BY YEAR(od.date)
    J'obtiens:
    date | nombre | depense | depense_liquide
    2011-07-27 18:31:01 | 84 | 8072.13 | 236.32
    2012-01-08 23:32:29 | 31 | 1605.79 | 238.68
    Groupement des 2 années 8072.13+1605.79=9677.92

    Même période, même calcul mais sans le group by, devrait retrouver exactement 9677.92

    Avec cette requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT od.date, COUNT(od.id) AS nombre, 
    SUM(DISTINCT(CASE WHEN od.id_achat_articles<>0 THEN od.montant_total END))+SUM(CASE WHEN od.id_achat_articles=0 THEN od.montant_total END) AS depense, 
    SUM(CASE WHEN od.id_type_paiement = 1 THEN od.debit ELSE 0 END) AS depense_liquide FROM operation_depenses od 
    LEFT JOIN achat_articles aa ON aa.id_achat=od.id_achat_articles
    WHERE (od.date BETWEEN '2011-01-26 01:31:01' AND '2012-01-26 23:00:00')
    J'obtiens pour la même période
    date | nombre | depense | depense_liquide
    2011-07-27 18:31:01 | 115 | 9624.17 | 475.00

    Sans le group by 9624.17, donc différent de 9677.92

    Comment expliquer ce type de problème ?
    La requête que j'aurais mis pour la dépense serait fausse?

    Merci

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

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

    votre dernière requête n'a pas de sens.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT od.date, COUNT(od.id) AS nombre, 
    SUM(DISTINCT(CASE WHEN od.id_achat_articles<>0 THEN od.montant_total END))+SUM(CASE WHEN od.id_achat_articles=0 THEN od.montant_total END) AS depense, 
    SUM(CASE WHEN od.id_type_paiement = 1 THEN od.debit ELSE 0 END) AS depense_liquide FROM operation_depenses od 
    LEFT JOIN achat_articles aa ON aa.id_achat=od.id_achat_articles
    WHERE (od.date BETWEEN '2011-01-26 01:31:01' AND '2012-01-26 23:00:00')
    Vous utilisez des fonctions d'agrégats, et une selection de colonne sans de group by.

    MySql étant très permissif sur les syntaxes utilisables, je ne sais pas ce qu'il ramène.

    Maintenant, je vous proposerai plutôt que vous nous décriviez un peu mieux vos deux tables et ce que vous cherchez à faire (sans simplifier)

  5. #5
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mai 2008
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 382
    Points : 191
    Points
    191
    Par défaut
    Voici la structure de mes tables:
    --
    -- Structure de la table `achat_articles`
    --
    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
    CREATE TABLE IF NOT EXISTS `achat_articles` (
      `id` int(12) NOT NULL AUTO_INCREMENT,
      `id_articles` int(12) NOT NULL,
      `id_doses` int(12) NOT NULL,
      `lots` int(12) NOT NULL,
      `quantites_par_lots` int(12) NOT NULL,
      `prix_reel_par_lots` decimal(7,2) NOT NULL,
      `quantites_totales` int(12) NOT NULL,
      `montant` decimal(7,2) NOT NULL,
      `valeur_vente` decimal(7,2) NOT NULL,
      `id_achat` int(12) NOT NULL,
      `id_filtre` int(12) NOT NULL,
      `id_sous_filtre` int(12) NOT NULL,
      `commentaires` text NOT NULL,
      `date` datetime NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=74 ;
    --
    -- Structure de la table `operation_depenses`
    --

    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
    CREATE TABLE IF NOT EXISTS `operation_depenses` (
      `id` int(12) NOT NULL AUTO_INCREMENT,
      `id_achat_articles` int(12) NOT NULL,
      `debit` decimal(7,2) NOT NULL,
      `frais_livraison` decimal(7,2) NOT NULL,
      `bon_reduction` decimal(7,2) NOT NULL,
      `montant_total` decimal(7,2) NOT NULL,
      `id_fournisseur` int(12) NOT NULL,
      `id_filtre` int(12) NOT NULL,
      `id_sous_filtre` int(12) NOT NULL,
      `id_type_paiement` int(12) NOT NULL,
      `numero_cheque` int(12) NOT NULL,
      `date` datetime NOT NULL,
      `id_membres` int(12) NOT NULL,
      `commentaires` text NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=70 ;
    J'ai donc fait une jointure de table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ON operation_depenses.id_achat_articles=achat_articles.id_achat
    -J'ai lorsque je fais un achat d'articles, plusieurs lignes qui me donne un id_achat
    -Lorsque je valide cet achat cela me créer une ligne dans la table operation_depenses avec l'id de l'achat.

    -Seulement je souhaite appliquer des filtres par articles dans mes achats.
    Donc j'utilise une jointure de table pour connaitre mes dépenses par filtres.
    Et ainsi filtrer les articles dans la table achat_articles.

    Je fais des synthèses des achats par année, mois, jours...
    Avec l'utilisation de Group BY, j'utilise donc réellement toujours group by

  6. #6
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mai 2008
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 382
    Points : 191
    Points
    191
    Par défaut
    Je re-poste pour clôturer ce sujet.

    J'ai ré-établi un cahier des charges sur toutes les solutions possibles!
    J'ai voulu écrire une seule requête pour toutes les solutions en y mettant des conditions.
    Je me suis rendu compte que je cherchais a trouver une requête trop complexe.

    Je vais donc tous reconstruire!

    Merci quand même pour votre patience,

    Salutations

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

Discussions similaires

  1. [Debutant] condition sur les champs
    Par nadhem dans le forum JDBC
    Réponses: 6
    Dernier message: 24/07/2006, 12h01
  2. condition sur un champ d'une table
    Par julio02200 dans le forum Access
    Réponses: 12
    Dernier message: 11/07/2006, 14h19
  3. Condition dans un champ
    Par vplf dans le forum Langage SQL
    Réponses: 3
    Dernier message: 15/05/2006, 10h59
  4. Réponses: 3
    Dernier message: 09/03/2006, 18h07
  5. Problème de requête avec cumul des conditions sur un champ
    Par UtopieAmbiante dans le forum Requêtes
    Réponses: 4
    Dernier message: 11/01/2006, 10h52

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