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

PHP & Base de données Discussion :

DISTINCT et les doublons


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Angelik
    Profil pro
    Inscrit en
    Août 2006
    Messages
    253
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 253
    Par défaut DISTINCT et les doublons
    Bonjour à tous !

    Je me permets de poster ce topic suite à un problème d'addition (sum) ... grr

    J'ai 3 tables (nommons-les table_membre, table1 et table2) dont voici les structures, ci-dessous :

    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
     
    --
    -- Structure de la table `table_membre`
    --
     
    CREATE TABLE IF NOT EXISTS `table_membre` (
      `id` int(11) NOT NULL auto_increment,
      `champ1` varchar(80) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM;
     
    --
    -- Contenu de la table `table_membre`
    --
     
    INSERT INTO `table_membre` (`id`, `champ1`) VALUES
    (1, 'Angelik');

    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
     
    --
    -- Structure de la table `table1`
    --
     
    CREATE TABLE IF NOT EXISTS `table1` (
      `id` int(11) NOT NULL auto_increment,
      `champ1` float NOT NULL,
      `champ2` varchar(80) NOT NULL default '',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM;
     
    --
    -- Contenu de la table `table1`
    --
     
    INSERT INTO `table1` (`id`, `champ1`, `champ2`) VALUES
    (1, 50, 'Angelik'),(1, 30, 'Angelik'),(1, 10, 'Angelik'),(1, 50, 'Angelik');

    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
     
    --
    -- Structure de la table `table2`
    --
     
    CREATE TABLE IF NOT EXISTS `table2` (
      `id` int(11) NOT NULL auto_increment,
      `champ1` float NOT NULL,
      `champ2` varchar(80) NOT NULL default '',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM;
     
    --
    -- Contenu de la table `table2`
    --
     
    INSERT INTO `table2` (`id`, `champ1`, `champ2`) VALUES
    (1, 20, 'Angelik'),(1, 20, 'Angelik'),(1, 10, 'Angelik'),(1, 5, 'Angelik');
    ...dans lesquelles je stocke mes valeurs dans leur champ respectif (nommons-le champ1 pour les 2 tables (table1 et table2), admettons 4 lignes pour chacune de ces tables avec les valeurs suivantes :

    50,30,10,50 ==> pour table1, champ1

    et

    20,20,10,5 ==> pour table2, champ1

    Lors de ma requête, je souhaite additionner ces 4 valeurs (pour chaque table) qui, somme toute vraisemblance, devrait nous donner 140 pour table1 et 55 pour table2

    Ainsi, je fais (naïvement) :

    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
     
    $search = mysql_query("SELECT table_membre.id, SUM(table1.champ1) AS valeur1, SUM(table2.champ1) AS valeur2
     
    		FROM table_membre
     
    		LEFT JOIN table1 ON table_membre.champ1 = table1.champ2
     
    		LEFT JOIN table2 ON table_membre.champ1 = table2.champ2
     
    		WHERE table_membre.champ1 = '$login'
     
    		GROUP BY table_membre.id") or die ("ERROR:" . mysql_error());
    		$row = mysql_num_rows($search);
     
     
    	$result1 = $row['valeur1'];
     
    	$result2 = $row['valeur2'];
     
     
    			while ($row = mysql_fetch_array($search)) {
     
    echo"result1 == ".$row['valeur1']."<br>";
    echo"result2 == ".$row['valeur2']."<br>";
     
    }
    Ce qui se passe est assez logique (quoique...) et ...

    result1 pour table1 me donne 560 au lieu de 140 avec le calcul suivant : ((50+30+10+50)*4) ==> 4 étant le nombre d'enregistrements pour table2

    et

    result2 pour table2 me donne 220 au lieu de 55 avec le calcul suivant : ((20+20+10+5)*4) ==> 4 étant le nombre d'enregistrements pour table1 cette fois ...

    De ces résultats, je me dis "tiens, je vais mettre un DISTINCT" dans ma requête tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(DISTINCT table1.champ1) AS valeur1, SUM(DISTINCT table2.champ1) AS valeur2
    (pas folle...croyais-je)

    mais là ... L'addition, qui semblait correcte au premier abord, exclut du calcul les doublons ='''''(

    donc pour result1, j'ai 90au lieu de 140 (50 étant enregistré 2 fois)

    et pour result2, j'ai 35au lieu de 55 (20 étant enregistré 2 fois aussi)


    CONCLUSION :

    Sans modifier la structure de ma requête (j'ai de bonnes raisons à cela, croyez-moi) est-il possible de pallier à ce problème ? y a t-il une astuce ou autre pour que le DISTINCT additionne également les doublons ? J'espère que oui ... et prends toutes les solutions !

    Merci d'avance pour toute l'attention et l'intérêt que vous porterez à ce post

    ++

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Août 2007
    Messages : 109
    Par défaut
    Bonjour,

    Il me parait difficile d'obtenir un résultat correcte en utilisant la forme de ta requête .
    En effet comme tu l'a vu par les différents tests que tu as effectués le moteur de requête sélectionne des données puis calcule les différents agrégats( SUM, AVG,MAX) que tu lui demande, or en effectuant ta somme sur une requête provenant de multiple tables tu multiplie automatiquement le nombre de ligne, exception faite des relations 1,1 .

    Je ne vois qu'une solution c'est d'effectuer tes sommes dans des sous requête filtrées du genre .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT table_membre.id,  R1.valeur1, R2.valeur AS valeur2
     
    		FROM table_membre
     
    		LEFT JOIN ( SELECT SUM(champ1) AS Valeur , champ2 FROM table1 GROUP BY champ2 ) AS R1 ON table_membre.champ1 = R1.champ2
     
    		LEFT JOIN (SELECT SUM(table1.champ1) AS Valeur , champ2 FROM table1 GROUP BY champ2 ) AS R2 ON table_membre.champ1 = R2.champ2
     
    		WHERE table_membre.champ1 = '$login'
     
    		GROUP BY table_membre.id"
    bien sûr cette requête est à optimiser en filtrant chaque sous requête afin de n'avoir que les éléments que tu désire, car il va calculer la somme de l'ensemble des enregistrements de la table pour chaque groupe (assez couteux non ?), mais elle à le mérite de faire ce que tu désire.

    Bon courage

Discussions similaires

  1. Comment supprimer les doublons
    Par djelloulc dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 17/09/2013, 14h30
  2. ne pas afficher les doublons avec distinct sous mysql
    Par Abou Zar dans le forum Requêtes
    Réponses: 8
    Dernier message: 25/01/2012, 11h49
  3. masquer les doublons sans utiliser distinct
    Par Misato dans le forum IHM
    Réponses: 3
    Dernier message: 07/06/2007, 11h06
  4. Distinct - éliminer les doublons
    Par chris801 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 27/03/2007, 23h22
  5. tri a bulle sans les doublons
    Par comme de bien entendu dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 10/03/2003, 16h29

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