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 :

Problème calcul erroné avec sum()


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut Problème calcul erroné avec sum()
    Bonjour,

    Afin de connaitre le prix de revient d'un Km par mois et par vehicule, j'ai cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT imma_actif, max(compteur)-min(compteur) as 'km', 
    DATE(max(gasoil.date)) AS 'date_max', 
    DATE(min(gasoil.date)) AS 'date_mini', 
    sum(prix) AS 'ca', 
    sum(prix)/(max(compteur)-min(compteur)) AS 'calcul'
    FROM vehicule
    LEFT JOIN gasoil ON gasoil.id_vehicule=vehicule.id_vehicule
    LEFT JOIN facture_ligne ON facture_ligne.id_annonce=annonce.id_annonce 
    WHERE DATE(gasoil.date) BETWEEN '$date_deb' AND '$date_fin' 
    AND facture_ligne.date_voyage BETWEEN '$date_deb' AND '$date_fin'
    GROUP BY vehicule.id_vehicule
    "compteur" est le kilométrage des véhicule entrées lors de la prise de gasoil

    Structure des tables

    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
     
    --
    -- Structure de la table `gasoil`
    --
     
    `gasoil` 
      `id_gasoil` int(11) NOT NULL auto_increment,
      `id_vehicule`  int(11) NOT NULL,
      `date` datetime NOT NULL,
      `compteur` varchar(10) NOT NULL,
      `consommation` varchar(10) NOT NULL,
      `volume` varchar(10) NOT NULL,
      PRIMARY KEY  (`id_gasoil`),
      KEY `imma` (`id_vehicule`),
      KEY `date` (`date`)
    )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    --
    -- Structure de la table `vehicule`
    --
     
    `vehicule`
      `id_vehicule` int(11) NOT NULL auto_increment,
      `imma_actif` varchar(10) collate latin1_general_ci NOT NULL,
      PRIMARY KEY  (`id_vehicule`)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    --
    -- Structure de la table `facture_ligne`
    --
     
    CREATE TABLE IF NOT EXISTS `facture_ligne` (
      `id_facture_ligne` int(11) NOT NULL auto_increment,
      `id_facture` int(11) NOT NULL,
      `date_voyage` date NOT NULL,
      `designation` text NOT NULL,
      `prix` decimal(10,2) NOT NULL,
      PRIMARY KEY  (`id_facture_ligne`),
      KEY `id_facture` (`id_facture`)
    Cette requete fonctionne mais donne un mauvais résultat au niveau de "ca". séparé en deux (Calcul du ca et des kms) fonctionnent avec les bon résultats.

    Je pense que le problème viens que je fait un max() et min() sur une table et un sum() sur une autre. Donc je pensais faire une sous-requête mais je ne vois pas comment récupérer mes résultats pour les calculs.

  2. #2
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par mouatte Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT imma_actif, max(compteur)-min(compteur) as km, 
    DATE(max(gasoil.date)) AS date_max, 
    DATE(min(gasoil.date)) AS date_mini, 
    sum(prix) AS ca, 
    sum(prix)/(max(compteur)-min(compteur)) AS calcul
    FROM vehicule
    LEFT JOIN gasoil ON gasoil.id_vehicule=vehicule.id_vehicule
    LEFT JOIN facture_ligne ON facture_ligne.id_annonce=annonce.id_annonce 
    WHERE DATE(gasoil.date) BETWEEN '$date_deb' AND '$date_fin' 
    AND facture_ligne.date_voyage BETWEEN '$date_deb' AND '$date_fin'
    GROUP BY vehicule.id_vehicule
    Déjà les quotes autour des noms d'alias sont inutiles.
    Citation Envoyé par mouatte Voir le message
    Je pense que le problème viens que je fait un max() et min() sur une table et un sum() sur une autre. Donc je pensais faire une sous-requête mais je ne vois pas comment récupérer mes résultats pour les calculs.
    Essaye avec des INNER JOIN.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Essaye avec des INNER JOIN.
    Bein ça marche pas mieux .
    J'ai mis "LEFT JOIN" car les clauses WHERE sont dans mes jointures normalement afin d'avoir tous les véhicules.

  4. #4
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 641
    Points
    4 641
    Par défaut
    salut,

    Peux tu nous donner un petit jeu d'essai (sous forme de create table + insert) puis le résultat attendu pour qu'on puisse reproduire le problème?

  5. #5
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LEFT JOIN facture_ligne ON facture_ligne.id_annonce=annonce.id_annonce
    Il n'y a pas de table "annonce". Je pense qu'il nous manque un bout de la requête.

    Dans ce genre de cas une approche est de lancer la requête à la main sans GROUP BY et en affichant seulement le détail des différentes valeurs, pour voir quelles sont les données présentes et s'assurer que l'on somme, maximise et autres ce que l'on voulait vraiment.

    Dans ce cas il me semble qu'il y a plusieurs relations 1-n : Les kilométrages et les pleins. Il n'est pas possible d'obtenir une jointure censée sur deux listes différentes, on fini toujours avec un produit cartésien sur les bras (les kilométrages croisés avec les pleins d'essence). Le plus simple serait à mon avis de faire deux requêtes et de diviser dans le code appelant. Avec des sous-requêtes ça se joue mais ça va être lourd, en code comme probablement en performances.

  6. #6
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Sivrît Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LEFT JOIN facture_ligne ON facture_ligne.id_annonce=annonce.id_annonce
    Il n'y a pas de table "annonce". Je pense qu'il nous manque un bout de la requête.
    Oui effectivement il n'y a pas de table annonce, car ma requete est un peu plus grande et fait appel à deux tables supplementaires pour lier l'identifiant du vehicule avec la table facture_ligne. J'ai donc fais un racourcci pour simplifier la requête. en faite j'aurais du mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT imma_actif, max(compteur)-min(compteur) AS km, 
    DATE(max(gasoil.date)) AS date_max, 
    DATE(min(gasoil.date)) AS date_mini, 
    sum(prix) AS ca, 
    sum(prix)/(max(compteur)-min(compteur)) AS calcul
    FROM vehicule
    LEFT JOIN gasoil ON gasoil.id_vehicule=vehicule.id_vehicule
    LEFT JOIN facture_ligne ON facture_ligne.id_vehicule=vehicule.id_vehicule 
    WHERE DATE(gasoil.date) BETWEEN '$date_deb' AND '$date_fin' 
    AND facture_ligne.date_voyage BETWEEN '$date_deb' AND '$date_fin'
    GROUP BY vehicule.id_vehicule
    Citation Envoyé par Sivrît Voir le message
    Dans ce genre de cas une approche est de lancer la requête à la main sans GROUP BY et en affichant seulement le détail des différentes valeurs, pour voir quelles sont les données présentes et s'assurer que l'on somme, maximise et autres ce que l'on voulait vraiment.
    C'est vrai je pourrai verifier comme ça, malgré le nombre de données, je pourrai partir sur un seul vehicule. Mais j'ai calculé les requêtes séparement (calul des kms, puis le CA) et ça me donne bien le bon résultat.

    Citation Envoyé par Sivrît Voir le message
    Dans ce cas il me semble qu'il y a plusieurs relations 1-n : Les kilométrages et les pleins. Il n'est pas possible d'obtenir une jointure censée sur deux listes différentes, on fini toujours avec un produit cartésien sur les bras (les kilométrages croisés avec les pleins d'essence). Le plus simple serait à mon avis de faire deux requêtes et de diviser dans le code appelant. Avec des sous-requêtes ça se joue mais ça va être lourd, en code comme probablement en performances.
    Je pense aussi à un produit cartésien, mais le problème c'est que je ne vois pas comment faire avec une sous-requete, peut-etre au niveau du FROM mais je n'arrive pas du tout à voir comment.

  7. #7
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Sivrît Voir le message
    [CODE]
    Dans ce genre de cas une approche est de lancer la requête à la main sans GROUP BY ...
    Bon j'ai fait le test, tu as une super idée, car je me suis aperçu que les valeurs sont répétées 13 fois (le nombre de fois qu'il est allé à la pompe dans le mois)

    Donc si je comprends bien, il faut que je fasse une sous-requête, mais je ne vois pas comment !

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Juste une petite remarque sur le point de départ :
    Citation Envoyé par mouatte Voir le message
    Afin de connaitre le prix de revient d'un Km par mois et par vehicule, j'ai cette requête :
    (...)

    "compteur" est le kilométrage des véhicule entrées lors de la prise de gasoil
    A ta place, je ne me fierais pas trop au kilométrage entré par les chauffeurs des véhicules lors de la prise de carburant à la pompe.
    Combien d'entre eux tapent n'importe quoi parce qu'ils ont oublié de noter le kilométrage avant d'aller à la caisse ?
    Je l'ai fait plusieurs fois et je ne suis sûrement pas le seul !
    Si tu analyses les factures successives d'un même véhicule, tu trouveras sûrement :
    - des écarts de plusieurs milliers de kilomètres ;
    - des kilomètres qui diminuent ;
    - des kilomètres qui ne bougent quasiment pas.

    Bon courage !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    La pompe est directement dans l'entreprise. Il y a aussi la géolocalisation qui est en cours de déploiement.
    Ayant testé un peu sur quelque véhicule, les données sont assez correct. De toute façon c'est un moyen d'avoir une tendance et mon des chiffres exact

  10. #10
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    j'ai beau tester plusieurs requêtes et lire les cours sur les jointure, je ne vois pas la solution.

    Dans ma table gasoil et ma table facture_ligne, j'ai bien plusieurs fois un vehicule mais étant donné que je passe par vehicule, ça ne devrai pas poser de problème, ou du moins je crois.

    Quelqu'un aurait une idée ?

  11. #11
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par Cybher Voir le message
    Peux tu nous donner un petit jeu d'essai (sous forme de create table + insert) puis le résultat attendu pour qu'on puisse reproduire le problème?
    J'ai la berlue ou on n'y a jamais eu droit ?
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  12. #12
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    J'ai la berlue ou on n'y a jamais eu droit ?
    Dur dur de faire l'echantillon

    Alors voici la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT imma_actif, max( compteur ) - min( compteur ) AS km, DATE( max( gasoil.date ) ) AS date_max, DATE( min( gasoil.date ) ) AS date_mini, sum( prix ) AS ca, sum( prix ) / ( max( compteur ) - min( compteur ) ) AS calcul
    FROM vehicule
    LEFT JOIN gasoil ON gasoil.id_vehicule = vehicule.id_vehicule
    LEFT JOIN facture_ligne ON facture_ligne.id_vehicule = vehicule.id_vehicule
    WHERE DATE( gasoil.date )
    BETWEEN '2008-10-01'
    AND '2008-10-31'
    AND facture_ligne.date_voyage
    BETWEEN '2008-10-01'
    AND '2008-10-31'
    Et voici un échantillon de la base

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    --
    -- Structure de la table `facture_ligne`
    --
     
    CREATE TABLE IF NOT EXISTS `facture_ligne` (
      `id_facture_ligne` int(11) NOT NULL auto_increment,
      `id_facture` int(11) NOT NULL,
      `id_vehicule` int(11) NOT NULL,
      `date_voyage` date NOT NULL,
      `designation` text NOT NULL,
      `prix` decimal(10,2) NOT NULL,
      PRIMARY KEY  (`id_facture_ligne`),
      KEY `id_facture` (`id_facture`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3410 ;
     
    --
    -- Contenu de la table `facture_ligne`
    --
     
    INSERT INTO `facture_ligne` (`id_facture_ligne`, `id_facture`, `id_vehicule`, `date_voyage`, `designation`, `prix`) VALUES
    (1849, 5859, 1, '2008-10-30', 'PRIMEURS 26 palette(s) \nExpéditeur : U.R.P.R (PERPIGNAN) Destinataire : LCM AIRE SUR LA LYS (AIRE SUR LA LYS)', 1290.00),
    (1922, 5862, 1, '2008-10-29', 'MESSAGERIE \nExpéditeur : DARFEUILLE GARONORD (AULNAY SOUS BOIS CEDEX) Destinataire : DARFEUILLE LE PONTET (LE PONTET )', 762.25),
    (1939, 5897, 1, '2008-10-29', 'INDUSTRIELS \nExpéditeur : VETURA SAS (PANTIN) Destinataire : TATI  AGDE (AGDE)', 460.00),
    (1966, 5850, 1, '2008-10-28', 'divers - (Ref : 1798429/7022045) \nExpéditeur : CAMPBELL (MONTEUX) Destinataire : CSF CREPY (CREPY EN VALOIS)', 450.00),
    (2015, 5853, 1, '2008-10-27', 'FRAIS \nExpéditeur : DISPAM CREPY (CREPY EN VALOIS) Destinataire : DISPAM LE PONTET (LE PONTET)', 1075.00),
    (2105, 5934, 1, '2008-10-25', 'viandes \nExpéditeur : GEL ALPES (MANOSQUE) Destinataire : WILLIAM SAURIN (CRECY SUR SERRE)', 1000.00),
    (2111, 5922, 1, '2008-10-24', 'FRAIS \nExpéditeur : DISPAM ORLEANS (ORLEANS) Destinataire : DISPAM LE PONTET (LE PONTET)', 1100.00),
    (2201, 5974, 1, '2008-10-23', 'PRIMEURS 1 palette(s) \nExpéditeur : MAS DES PLATANES (LE THOR) Destinataire : LA RENOMIERE BAT B2 (RUNGIS COMPLEXE)', 44.00),
    (2207, 5977, 1, '2008-10-23', 'PRIMEURS 2 palette(s) \nExpéditeur : IDYL (CHATEAURENARD) Destinataire : VINAS RUNGIS BAT C2 (RUNGIS)', 84.00),
    (2228, 5922, 1, '2008-10-22', 'FRAIS \nExpéditeur : DISPAM NORD /CABY (SAINT ANDREE) Destinataire : DISPAM LE PONTET (LE PONTET)', 1480.00),
    (2320, 5972, 1, '2008-10-21', 'PRIMEURS \nExpéditeur : DIVERS PERPIGNAN (PERPIGNAN) Destinataire : SANTOLARIA (LOMME CEDEX)', 1300.00),
    (2379, 5924, 1, '2008-10-20', 'PRIMEURS 9 palette(s) \nExpéditeur : JOUFFRUIT S.A.R.L (CAVAILLON) Destinataire : LIDL LUNEL (LUNEL CEDEX)', 171.00),
    (2465, 6026, 1, '2008-10-17', 'FRAIS \nExpéditeur : DISPAM HELIODIS (VAL DE REUIL) Destinataire : DISPAM LE PONTET (LE PONTET)', 1000.00),
    (2568, 6032, 1, '2008-10-16', 'INDUSTRIEL - (Ref : 1786057/7021854) \nExpéditeur : CAMPBELL FRANCE S.A.S (SORGUES) Destinataire : AUCHAN (EPONE)', 450.00),
    (2576, 6026, 1, '2008-10-15', 'FRAIS \nExpéditeur : DISPAM CREPY (CREPY EN VALOIS) Destinataire : DISPAM LE PONTET (LE PONTET)', 1075.00),
    (2655, 6031, 1, '2008-10-14', 'PRIMEURS 12 palette(s) \nExpéditeur : TRANSCOSATAL (PLAN D ORGON) Destinataire : CSF CREPY (CREPY EN VALOIS)', 528.00),
    (2703, 6102, 1, '2008-10-14', 'INDUSTRIEL - (Ref : 1786661/7002506) \nExpéditeur : LAPHAL INDUSTRIES (ROUSSET) Destinataire : EURODEP (LAGNY LE SEC)', 460.00),
    (2776, 6127, 1, '2008-10-11', 'FRAIS \nExpéditeur : DISPAM HELIODIS (VAL DE REUIL) Destinataire : DISPAM LE PONTET (LE PONTET)', 1100.00),
    (2860, 6171, 1, '2008-10-10', 'FRAIS \nExpéditeur : GLF (COMMUNAY) Destinataire : ED /DIVERS CLIENTS (LOUVIER)', 680.00),
    (2885, 6177, 1, '2008-10-09', 'POMMES 1 palette(s) \nExpéditeur : CARREFOUR DAMMARTIN EN GOELE (DAMMARTIN EN GOELE) Destinataire : PROVENCE COMTAT (LE THOR)', 80.00),
    (2888, 6179, 1, '2008-10-09', 'POMMES 6 palette(s) \nExpéditeur : CSF CREPY (CREPY EN VALOIS) Destinataire : CRENO IMPEX CHATEAURENARD (CHATEAURENARD CEDEX)', 480.00),
    (2902, 6162, 1, '2008-10-09', 'MESSAGERIE \nExpéditeur : DARFEUILLE GARONORD (AULNAY SOUS BOIS CEDEX) Destinataire : DARFEUILLE LE PONTET (LE PONTET )', 762.25),
    (2917, 6147, 1, '2008-10-09', 'RAISINS 1 palette(s) \nExpéditeur : CARREFOUR DAMMARTIN EN GOELE (DAMMARTIN EN GOELE) Destinataire : TONFONI ET CIE (PLAN D ORGON)', 80.00),
    (2956, 6133, 1, '2008-10-08', 'PRIMEURS 2 palette(s) \nExpéditeur : TRANSCOSATAL (PLAN D ORGON) Destinataire : CSF CREPY (CREPY EN VALOIS)', 96.00),
    (2958, 6135, 1, '2008-10-08', 'PRIMEURS 10 palette(s) \nExpéditeur : TRANSCOSATAL (PLAN D ORGON) Destinataire : CARREFOUR DAMMARTIN EN GOELE (DAMMARTIN EN GOELE)', 44.00),
    (3051, 6162, 1, '2008-10-07', 'MESSAGERIE \nExpéditeur : DARFEUILLE GARONORD (AULNAY SOUS BOIS CEDEX) Destinataire : DARFEUILLE LE PONTET (LE PONTET )', 762.25),
    (3074, 6222, 1, '2008-10-07', 'INDUSTRIELS \nExpéditeur : VETURA SAS (PANTIN) Destinataire : TATI  AGDE (AGDE)', 460.00),
    (3156, 6236, 1, '2008-10-06', 'INDUS - (Ref : 1280053) \nExpéditeur : ASTRE IMPEX (BELMONT TRAMONET) Destinataire : SYSTEME U (CARQUEFOU)', 600.00),
    (3219, 6244, 1, '2008-10-03', 'RAISINS 2 palette(s) \nExpéditeur : CSF CREPY (CREPY EN VALOIS) Destinataire : CRENO IMPEX CHATEAURENARD (CHATEAURENARD CEDEX)', 160.00),
    (3269, 6284, 1, '2008-10-02', 'FRAIS \nExpéditeur : DISPAM RENNES (CRAON) Destinataire : DISPAM LE PONTET (LE PONTET)', 1450.00),
    (3409, 6315, 1, '2008-10-01', 'INDUSTRIEL - (Ref : 592994) \nExpéditeur : SETEL (CAVAILLON CEDEX) Destinataire : DLP PARC VENDEE SUD LOIRE 2 (BOUFFERE)', 800.00);
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `gasoil`
    --
     
    CREATE TABLE IF NOT EXISTS `gasoil` (
      `id_gasoil` int(11) NOT NULL auto_increment,
      `id_vehicule` int(11) NOT NULL,
      `date` datetime NOT NULL,
      `compteur` varchar(10) NOT NULL,
      `consommation` varchar(10) NOT NULL,
      `volume` varchar(10) NOT NULL,
      PRIMARY KEY  (`id_gasoil`),
      KEY `date` (`date`),
      KEY `id_vehicule` (`id_vehicule`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2352 ;
     
    --
    -- Contenu de la table `gasoil`
    --
     
    INSERT INTO `gasoil` (`id_gasoil`, `id_vehicule`, `date`, `compteur`, `consommation`, `volume`) VALUES
    (1900, 1, '2008-10-01 15:19:39', '433467', '33.42', '684.06'),
    (1935, 1, '2008-10-03 01:31:39', '435420', '39.16', '764.87'),
    (2005, 1, '2008-10-08 17:54:08', '437214', '27.87', '500'),
    (2035, 1, '2008-10-10 10:39:49', '438823', '40.58', '653'),
    (2070, 1, '2008-10-12 05:26:16', '440513', '32.07', '542.06'),
    (2101, 1, '2008-10-20 16:12:35', '444699', '34.52', '718.06'),
    (2188, 1, '2008-10-16 18:15:08', '442619', '31.39', '661.06'),
    (2240, 1, '2008-10-23 02:25:48', '447128', '32.92', '799.68'),
    (2253, 1, '2008-10-23 18:21:28', '447237', '76.15', '83'),
    (2278, 1, '2008-10-26 18:50:08', '448773', '31.25', '480.06'),
    (2299, 1, '2008-10-28 03:48:02', '450443', '35.93', '600'),
    (2325, 1, '2008-10-28 23:20:55', '450968', '39.39', '206.81'),
    (2351, 1, '2008-10-30 17:23:04', '452500', '38.84', '595');
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `vehicule`
    --
     
    CREATE TABLE IF NOT EXISTS `vehicule` (
      `id_vehicule` int(11) NOT NULL auto_increment,
      `imma_actif` varchar(10) collate latin1_general_ci NOT NULL,
      PRIMARY KEY  (`id_vehicule`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=2 ;
     
    --
    -- Contenu de la table `vehicule`
    --
     
    INSERT INTO `vehicule` (`id_vehicule`, `imma_actif`) VALUES
    (1, '412 RE 34');
    Les Kms sont bon, mais la somme des km devrait être de 20283,75 au lieu de 263688,75.
    Et quand on fait 263688,75 / 20283,75 on obtient bien 13, le nombre de ligne de la table gasoil

  13. #13
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Bon, je comprends mieux d'où provient le problème. Comme souvent, à l'origine, je suspecte une erreur de conception.
    Pourquoi as-tu besoin de la table facture_ligne dans cette requête, car ton problème vient de là ?
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  14. #14
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Pourquoi as-tu besoin de la table facture_ligne dans cette requête, car ton problème vient de là ?
    J'en ai besoin pour récuper le chiffre d'affaire, en parcourant les factures.
    il faut que je récupère le chiffre d'affaire par vehicule et le diviser par les kms.

  15. #15
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Ok, comme les tables facture_linge et gasoil ne sont pas en relation 1-1 la jointure via l'identifiant du véhicule provoque des doublons dans le comptage.
    Donc, il faut faire une sous-requête corrélée pour calculer soit la consommation soit le chiffre d'affaire si tu veux faire tout en une seule requête.
    Si ta version de SQL supporte les sous-requêtes c'est envisageable, même si ce n'est pas recommandé en termes de gourmandise en ressources sur le serveur.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  16. #16
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Ok, comme les tables facture_linge et gasoil ne sont pas en relation 1-1 la jointure via l'identifiant du véhicule provoque des doublons dans le comptage.
    Tout à fait

    Citation Envoyé par Maljuna Kris Voir le message
    Donc, il faut faire une sous-requête corrélée pour calculer soit la consommation soit le chiffre d'affaire si tu veux faire tout en une seule requête.
    Actuellement elle est en deux requêtes et deux tableaux PHP et ça fonctionne. Là ou est le problème c'est que ma requête doit être encore plus complexe (C'est pour ça que je souhaite la faire en une fois), car par exemple un véhicule ne fait pas toujours le plein le premier jour et le dernier jour du mois.
    Donc en fait, je fais un between pour selectionner les date des factures que je veux. Actuellement c'est le premier et dernier jour, mais ça doit être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    facture_ligne.date_voyage between min(gasoil.date) and max(gasoil.date)
    Mais quand je mets ça dans la clause Where MySql m'insulte (C'est surement justifé !).

    Citation Envoyé par Maljuna Kris Voir le message
    Si ta version de SQL supporte les sous-requêtes c'est envisageable, même si ce n'est pas recommandé en termes de gourmandise en ressources sur le serveur.
    J'utilise la version 5.0.67 de MySql. Niveau gourmandise de la requête, c'est pas très grave, le principale c'est que ça fonctionne.

  17. #17
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    J'ai eu un rejet pour dépassement de temps de connexion sous Wamp Server 2 avec cette requête qui n'attaque que les petits extraits que tu nous a confiés :
    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
    SELECT v.imma_actif,g.km,g.date_max,g.date_mini,f.ca, f.ca / g.km AS calcul
    FROM vehicule v
    LEFT JOIN (SELECT gasoil.id_vehicule,
                MAX( gasoil.compteur ) - MIN( gasoil.compteur ) AS km,
                DATE( MAX( gasoil.`date` ) ) AS date_max,
                DATE( MIN( gasoil.`date`) ) AS date_mini
                FROM gasoil 
                WHERE DATE( gasoil.`date` ) 
                BETWEEN '2008-10-01' AND '2008-10-31')as g 
    ON g.id_vehicule = v.id_vehicule
    LEFT JOIN (SELECT sum( fl.prix ) AS ca, fl.id_vehicule
                FROM facture_ligne fl
                WHERE fl.date_voyage 
                BETWEEN '2008-10-01' AND '2008-10-31')
                AS f
    ON f.id_vehicule = v.id_vehicule;
    C'est dire ce que ça va donner sur des tables conséquentes.
    J'ai viré le GROUP BY qui était inutile.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  18. #18
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    J'ai eu un rejet pour dépassement de temps de connexion sous Wamp Server 2 avec cette requête qui n'attaque que les petits extraits que tu nous a confiés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Affichage des enregistrements 0 - 0 (1 total, Traitement en 0.0289 sec.)
    Je suis sur Ubuntu Intrepid pour le développement.
    Avec le serveur de production 5.0.51a ça ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
    C'est pas grave je monterai en version. J'ai testé avec 5.1.30 avec Wamp et ca marche.

    Sinon je veux pas trop abuser, mais je n'arrive pas à limité la date de facture_ligne, par le resutat de MIN(gasoil.`date`)) et MAX(gasoil.`date`))

    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
     SELECT v.imma_actif, g.km, g.date_max, g.date_mini, f.ca, f.ca / g.km AS calcul
    FROM vehicule v
    LEFT JOIN (
     
    SELECT gasoil.id_vehicule, MAX( gasoil.compteur ) - MIN( gasoil.compteur ) AS km, DATE( MAX( gasoil.`date` ) ) AS date_max, DATE( MIN( gasoil.`date` ) ) AS date_mini
    FROM gasoil
    WHERE DATE( gasoil.`date` )
    BETWEEN '2008-10-01'
    AND '2008-10-31'
    ) AS g ON g.id_vehicule = v.id_vehicule
    LEFT JOIN (
     
    SELECT sum( fl.prix ) AS ca, fl.id_vehicule
    FROM facture_ligne fl
    WHERE fl.date_voyage
    BETWEEN max_date
    AND date_mini
    ) AS f ON f.id_vehicule = v.id_vehicule
     
    MySQL a répondu:Documentation
    #1054 - Unknown column 'max_date' in 'where clause'
    Aie, pas très content !

  19. #19
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    MySQL a réponduocumentation
    #1054 - Unknown column 'max_date' in 'where clause'
    Logique, essaye avec le préfixe g.max_date et g.min_date
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  20. #20
    Membre à l'essai
    Inscrit en
    Août 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2005
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Logique, essaye avec le préfixe g.max_date et g.min_date
    Bein non, veux pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1054 - Unknown column 'g.date_mini' in 'where clause'

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

Discussions similaires

  1. problème de jointure avec calcul
    Par nine dans le forum Langage SQL
    Réponses: 20
    Dernier message: 11/06/2009, 16h35
  2. Problème de requete avec SUM
    Par fatiinfo dans le forum Hibernate
    Réponses: 2
    Dernier message: 27/08/2008, 16h18
  3. Problème calcul arithmétique avec des float
    Par tioneb369 dans le forum Langage
    Réponses: 4
    Dernier message: 18/09/2007, 14h35
  4. erreur de calcul avec SUM
    Par peyro51 dans le forum Excel
    Réponses: 6
    Dernier message: 14/07/2007, 09h14
  5. [SQL Access] Problème avec Sum()
    Par badgam piero dans le forum Access
    Réponses: 5
    Dernier message: 12/12/2005, 16h00

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